Subodh Mankar
Subodh Mankar

Reputation: 365

skipped 147 frames! The application may be doing too much work on its main thread

I understand the meaning of this error. I found many similar questions here at stackoverflow.com and I have tried to implement the answers those were suggested but still I am getting this error. What I am trying to do is using php web service I am extracting the data from mysql database server and trying to display it in listview using AsyncTask as follows:

class LoadAllProducts extends AsyncTask<String, String, ArrayList<HashMap<String, String>>> 
{
    ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
    protected ArrayList<HashMap<String, String>> doInBackground(String... args)
    {
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        JSONObject json = jParser.makeHttpRequest(url_all_products, "GET", params);

        Log.d("All Products: ", json.toString());
        try {

                JSONArray  files = json.getJSONArray(TAG_FILES);
                for(int i=0;i<files.length();i++)
                {                     
                    HashMap<String, String> map = new HashMap<String, String>();    
                    JSONObject e = files.getJSONObject(i);


                    String file_name = e.getString(TAG_FILE_NAME);
                    String sender = e.getString(TAG_SENDER);
                    String subject = e.getString(TAG_SUBJECT);


                    map.put(TAG_SENDER, sender);
                    map.put(TAG_SUBJECT, subject);

                    mylist.add(map);            
                } 


        } catch (JSONException e) 
        {
            e.printStackTrace();
            Log.e("log_tag", "Error parsing data "+e.toString());
        }

        return mylist;

    }

This was suggested in many answers that all the processing should be done in doInBackground function. Now below is the code to display this arraylist in ListView

 protected void onPostExecute(String file_url) 
    {

        pDialog.dismiss();

        runOnUiThread(new Runnable() 
        {
            public void run() 
            {
                String[] from = { TAG_SENDER, TAG_SUBJECT };
                int[] to = { android.R.id.text1, android.R.id.text2 };


                ListAdapter adapter = new SimpleAdapter(AllProductsActivity.this, mylist,
                        android.R.layout.simple_list_item_2, from , to);
                      setListAdapter(adapter);

            }
        });

    }

Please Help cause first of all I am a beginner of android and I dont have any clue how to solve this problem . Please check my code and let me know the problem.

Upvotes: 3

Views: 14628

Answers (2)

Ranjit
Ranjit

Reputation: 5150

This type of error will come if your main thread doing so much work. Basically skip frames will happen maximum time when we test our app in emulator, because its already slow and unable to handle huge operation like a device.

I saw a simple problem in your code. We know onPostExecute() runs on MainThread, But still you use runOnUiThread(new Runnable() in onPostExecute() .

You doinbackground method returns an ArrayList , but your onpostexecute hold a string..

Change it as my onPostExecute' parameter that is the ArrayList(mylist)you use in your adapter.

EDIT

  class LoadAllProducts extends AsyncTask<String, String, ArrayList<HashMap<String, String>>> {

    ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
    protected ArrayList<HashMap<String, String>> doInBackground(String... args){
    HttpClient client = new DefaultHttpClient();
    HttpGet getData = new HttpGet("your_url");
    HttpResponse response = client.execute(getData);
    BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
    String data = "";

    while((data = br.readLine()) != null){
    JsonArray arr = new JsonArray(data);
       for(int i=0;i<arr.length();i++)
            {                     
                HashMap<String, String> map = new HashMap<String, String>();    
                JSONObject e = arr.getJSONObject(i);

                String file_name = e.getString(TAG_FILE_NAME);
                String sender = e.getString(TAG_SENDER);
                String subject = e.getString(TAG_SUBJECT);


                map.put(TAG_SENDER, sender);
                map.put(TAG_SUBJECT, subject);

                mylist.add(map);            

    }

    return mylist;

}

 protected void onPostExecute(ArrayList<HashMap<String, String>> mylist) {
            String[] from = { TAG_SENDER, TAG_SUBJECT };
            int[] to = { android.R.id.text1, android.R.id.text2 };


            ListAdapter adapter = new SimpleAdapter(AllProductsActivity.this, mylist,
                    android.R.layout.simple_list_item_2, from , to);
                  setListAdapter(adapter);

              pDialog.dismiss();

        }

Upvotes: 8

Eric Simonton
Eric Simonton

Reputation: 6029

I'm sorry this is not a super informed answer, but I have 2 suggestions. First, eliminate the runOnUiThread call, because onPostExecute already runs on the ui thread (that is the point of the method). That will not help with any frame skipping, but at least you can get rid of some unneeded code.

Second, create the ListAdapter in doInBackground. I doubt it will make much difference, but you might as well get as much off the UI thread as possible. So, instead of AsyncTask<String, String, ArrayList<HashMap<String, String>>> you will use AsyncTask<String, String, ListAdapter>. That leaves only 2 method calls in onPostExecute, pDialog.dismiss and setListAdapter. You can't get any more efficient than that. If it still skips frames, I would blame the debugger and move on.

Upvotes: 2

Related Questions