跳过60帧!该应用程序可能会做太多的工作,它的主线程 [英] Skipped 60 frames! The application may be doing too much work on its main thread

查看:255
本文介绍了跳过60帧!该应用程序可能会做太多的工作,它的主线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个应用程序,应该从一个web服务的JSON响应,写的每一个元素在列表视图,我看过,我应该是的AsyncTask 获得HTTP响应,我做到了,我可以从Web服务中检索数据和 TextViews 显示它们。但是,当我尝试显示在列表视图元素不显示的什么,并给了我下面的消息在logcat中: 06-05 19:44:27.418:I /编导(20731):跳过60帧!该应用程序可能会做它的主线程的工作太多了。

这是我的主要code:

 公共类MainActivity延伸活动{

    私有静态的JSONObject响应=新的JSONObject();
    私人的ArrayList<的SearchResult>结果=新的ArrayList<的SearchResult>();
    私人的SearchResult SR1 = NULL;

    @覆盖
    保护无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_main);

        新的LoginAction()执行();

        ArrayList的<的SearchResult>的SearchResult =结果;
        最终的ListView LV1 =(ListView控件)findViewById(R.id.ListView01);
        lv1.setAdapter(新MyCustomBaseAdapter(这一点,SearchResult所));
    }

    @覆盖
    公共布尔onCreateOptionsMenu(功能菜单){
        //充气菜单;这增加了项目操作栏,如果它是present。
        。getMenuInflater()膨胀(R.menu.main,菜单);
        返回true;
    }

    私有类的LoginAction扩展了AsyncTask的<字符串,太虚,字符串> {

        @覆盖
        保护字符串doInBackground(字符串... PARAMS){

            地图<字符串,字符串> callArgs =新的HashMap<字符串,字符串>(1);

            callArgs.put(suuid,dtr0bdQGcqwSh3QO7fVwgVfBNWog6mvEbAyljlLX9E642Yfmur);

            尝试 {
                响应= EventPulseCloud.call(的listEvents,callArgs);
            }赶上(HttpClientException E){
                e.printStackTrace();
            }赶上(IOException异常E){
                e.printStackTrace();
            }赶上(JsonException E){
                e.printStackTrace();
            }

            返回response.get(类型)的toString()。
        }

        保护无效onPostExecute(字符串结果){

            如果(result.equals(成功)){
                JsonArray纪录= NULL;
                尝试 {
                    记录= response.getObject(数据)的getArray(史记)。
                }赶上(JsonException E){
                    e.printStackTrace();
                }

                的for(int i = 0; I< records.count();我++){
                    JSONObject的纪录=(的JSONObject)records.get(我);
                    SR1 =新的SearchResult();
                    sr1.setAddress(record.get(地址)的toString());
                    results.add(SR1);
                }
            }
        }
    }
    }
 

我的列表适配器:

 公共类MyCustomBaseAdapter扩展了BaseAdapter {
    私有静态的ArrayList<的SearchResult> sea​​rchArrayList;

    私人LayoutInflater mInflater;

    公共MyCustomBaseAdapter(上下文的背景下,ArrayList的<的SearchResult>的结果){
        sea​​rchArrayList =结果;
        mInflater = LayoutInflater.from(上下文);
    }

    公众诠释getCount将(){
        返回searchArrayList.size();
    }

    公共对象的getItem(INT位置){
        返回searchArrayList.get(位置);
    }

    众长getItemId(INT位置){
        返回的位置;
    }

    公共查看getView(INT位置,查看convertView,ViewGroup中父){
        ViewHolder持有人;
        如果(convertView == NULL){
            convertView = mInflater.inflate(R.layout.custom_row_view,NULL);
            持有人=新ViewHolder();
            holder.txtAddress =(TextView中)convertView.findViewById(R.id.address);

            convertView.setTag(保持器);
        } 其他 {
            支架=(ViewHolder)convertView.getTag();
        }

        holder.txtAddress.setText(searchArrayList.get(位置).getAddress());

        返回convertView;
    }

    静态类ViewHolder {
        TextView的txtAddress;
    }
}
 

最后,SearchResults.java:

 公共类的SearchResult {
    私人字符串地址=;

    公共无效setAddress(字符串地址){
        this.address =地址;
    }

    公共字符串的getAddress(){
        退货地址;
    }
}
 

那么,我该怎么办错了吗?你有这个想法?

感谢你。

解决方案

 私有类的LoginAction扩展AsyncTaskList<字符串,无效的ArrayList<信息搜索结果>> {

    @覆盖
    受保护的ArrayList<信息搜索结果> doInBackground(字符串... PARAMS){
        名单<的SearchResult> resultList =新的ArrayList<的SearchResult>();

        地图<字符串,字符串> callArgs =新的HashMap<字符串,字符串>(1);

        callArgs.put(suuid,dtr0bdQGcqwSh3QO7fVwgVfBNWog6mvEbAyljlLX9E642Yfmur);

        尝试 {
            响应= EventPulseCloud.call(的listEvents,callArgs);
        }赶上(HttpClientException E){
            e.printStackTrace();
        }赶上(IOException异常E){
            e.printStackTrace();
        }赶上(JsonException E){
            e.printStackTrace();
        }
      //看到这里我运行的循环在后台所以它不是在主线程,然后将列表传递关闭,以这种方式所有的主线程也被设置在适配器列表中onpostexecute和数据更新和清单的通知它应该更新在屏幕上
       如果(response.get(类型)。的toString()。等于(成功)){
            JsonArray纪录= NULL;
            尝试 {
                记录= response.getObject(数据)的getArray(史记)。
            }赶上(JsonException E){
                e.printStackTrace();
            }

            的for(int i = 0; I< records.count();我++){
                JSONObject的纪录=(的JSONObject)records.get(我);
                SR1 =新的SearchResult();
                sr1.setAddress(record.get(地址)的toString());
                resultList.add(SR1);
            }
        }
        返回resultList;
    }

    保护无效onPostExecute(ArrayList中<信息搜索结果> resultList){
          setListItems(resultList);

    }
}
}
 

在该OnCreate中与您的所有其他全局变量

添加此行

  //这里要创建一个适配器变种与您的基础转接器,您可以设置它的更新列表后,当您从互联网人口数据
         ArrayList的<的SearchResult>的SearchResult =新的ArrayList<的SearchResult>();
         MyCustomBaseAdapter适配器=新MyCustomBaseAdapter(这一点,SearchResult所)
 

粘贴在您的onCreate方法(更换)

  //这里只是code来更新你的主要方法,以反映我所做的更改
  @覆盖
  保护无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_main);

    新的LoginAction()执行();

    最终的ListView LV1 =(ListView控件)findViewById(R.id.ListView01);
    lv1.setAdapter(适配器);

}
 

和此方法添加到适配器(MyCustomnBaseAdapter类)code

 公共无效setListItems(ArrayList中<信息搜索结果> newList){
     sea​​rchArrayList = newList;
     notifyDataSetChanged();
}
 

I'm working on a App that should get a JSON response from a webservice and write every element in a listview, I have read that I should work with AsyncTask to get the HTTP Response and I did it and I could retrieve data from the webservice and display them in TextViews. But when I try to display elements in a listview it doesn't display anything and gives me the following message in the logcat : 06-05 19:44:27.418: I/Choreographer(20731): Skipped 60 frames! The application may be doing too much work on its main thread.

here's my main code :

public class MainActivity extends Activity {

    private static JsonObject response = new JsonObject();
    private ArrayList<SearchResults> results = new ArrayList<SearchResults>(); 
    private SearchResults sr1 = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new LoginAction().execute("");  

        ArrayList<SearchResults> searchResults = results;
        final ListView lv1 = (ListView) findViewById(R.id.ListView01);
        lv1.setAdapter(new MyCustomBaseAdapter(this, searchResults));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    private class LoginAction extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {

            Map<String, String> callArgs = new HashMap<String, String>(1);

            callArgs.put("suuid", "dtr0bdQGcqwSh3QO7fVwgVfBNWog6mvEbAyljlLX9E642Yfmur");

            try {
                response = EventPulseCloud.call("ListEvents", callArgs);
            } catch (HttpClientException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JsonException e) {
                e.printStackTrace();
            } 

            return response.get("Type").toString();
        }

        protected void onPostExecute(String result) {

            if(result.equals("success")) {
                JsonArray records = null;
                try {
                    records = response.getObject ("Data").getArray ("Records");
                } catch (JsonException e) {
                    e.printStackTrace();
                }

                for(int i = 0; i < records.count(); i++) {
                    JsonObject record = (JsonObject) records.get(i);
                    sr1 = new SearchResults();
                    sr1.setAddress(record.get("address").toString());
                    results.add(sr1);
                }
            }   
        }   
    }
    }

My list adapter :

public class MyCustomBaseAdapter extends BaseAdapter {
    private static ArrayList<SearchResults> searchArrayList;

    private LayoutInflater mInflater;

    public MyCustomBaseAdapter(Context context, ArrayList<SearchResults> results) {
        searchArrayList = results;
        mInflater = LayoutInflater.from(context);
    }

    public int getCount() {
        return searchArrayList.size();
    }

    public Object getItem(int position) {
        return searchArrayList.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.custom_row_view, null);
            holder = new ViewHolder();
            holder.txtAddress = (TextView) convertView.findViewById(R.id.address);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.txtAddress.setText(searchArrayList.get(position).getAddress());

        return convertView;
    }

    static class ViewHolder {
        TextView txtAddress;
    }
}

and finally, SearchResults.java :

public class SearchResults {
    private String address = "";

    public void setAddress(String address) {
        this.address = address;
    }

    public String getAddress() {
        return address;
    }
}

So, what do I do wrong ? Do you have an idea about this ?

Thank you.

解决方案

private class LoginAction extends AsyncTaskList<String, Void, ArrayList<SearchResult>> {

    @Override
    protected ArrayList<SearchResult> doInBackground(String... params) {
        List<SearchResults> resultList =  new ArrayList<SearchResults>();

        Map<String, String> callArgs = new HashMap<String, String>(1);

        callArgs.put("suuid", "dtr0bdQGcqwSh3QO7fVwgVfBNWog6mvEbAyljlLX9E642Yfmur");

        try {
            response = EventPulseCloud.call("ListEvents", callArgs);
        } catch (HttpClientException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JsonException e) {
            e.printStackTrace();
        } 
      //See here I am running the loop in the background so its not on the main thread, then passing the list off to the onpostexecute that way all the main thread does is set the adapter list and notify it of the data update and the list should be updated on the screen
       if( response.get("Type").toString().equals("success")) {
            JsonArray records = null;
            try {
                records = response.getObject ("Data").getArray ("Records");
            } catch (JsonException e) {
                e.printStackTrace();
            }

            for(int i = 0; i < records.count(); i++) {
                JsonObject record = (JsonObject) records.get(i);
                sr1 = new SearchResults();
                sr1.setAddress(record.get("address").toString());
                resultList.add(sr1);
            }
        }  
        return resultList;
    }

    protected void onPostExecute(ArrayList<SearchResult> resultList) {
          setListItems(resultList);

    }   
}
}

add this line before the oncreate with all your other global var

   //here you want to create an adapter var with your base adapter so you can set it the updated list later when you have populated data from the internet
         ArrayList<SearchResults> searchResults = new ArrayList<SearchResults>();
         MyCustomBaseAdapter adapter = new MyCustomBaseAdapter(this, searchResults)

paste this over your oncreate method (replace it)

//here is just the code to update your main method to reflect all the changes I made
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    new LoginAction().execute("");  

    final ListView lv1 = (ListView) findViewById(R.id.ListView01);
    lv1.setAdapter(adapter);

}

and add this method to the adapter(MyCustomnBaseAdapter class) code

public void setListItems(ArrayList<SearchResult> newList) {
     searchArrayList = newList;
     notifyDataSetChanged();
}

这篇关于跳过60帧!该应用程序可能会做太多的工作,它的主线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆