beginner
beginner

Reputation: 389

Skipped 451 frames! The application may be doing too much work on its main thread

I know there are similar problems in here. But i tried the possible solutions and still having error.

I am creating a list view with image and text views. the path of the image is retrieved from database. Now i want to load the images in the rows of the list view. In my activity i am doing this in onCreate Code snippet is

new Thread(new Runnable() {
     @Override
        public void run() {
            if (Looper.myLooper() == null)
                Looper.prepare();
                adapter = new ViewAdapter(getApplicationContext(), cursor);
            }
    }).start();

in the Adapter class i am doing this

class ViewAdapter extends CursorAdapter {
        @Override
        public void bindView(View view, Context context, Cursor cur) {

            new ImgAdapter_My_list(image,pic).execute();
 ....
           }
}

The ImgAdapter_My_list extends asynctask to lower the load on the main thread

public class ImgAdapter_My_list extends  AsyncTask<Object, Void, Bitmap>       {

    private ImageView imv;
    private String path;

    public ImgAdapter_My_list(ImageView imv,String path) {
        this.imv = imv;
        this.path=path;
    }

    @Override
    protected Bitmap doInBackground(Object... params) {
        Bitmap bitmap = null;
        File file = new File(Environment.getExternalStorageDirectory()
                .getAbsolutePath() + path);

        if (file.exists()) {
            bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
        }
        //Bitmap bitmap = ((BitmapDrawable)imv.getDrawable()).getBitmap();

        return bitmap;
    }

    @Override
    protected void onPostExecute(Bitmap result) {

        if (result != null && imv != null) {
            Log.d("test", "post exe  success");
            imv.setVisibility(View.VISIBLE);
            imv.setImageBitmap(result);
        } else {
            Log.d("test","result=" + String.valueOf(result == null)); //result is null here
            Log.d("test","imv=" + String.valueOf(imv == null));
            Log.d("test","fail");
            imv.setVisibility(View.GONE);
        }
    }
}

And after all this i get too much work on main thread error. PLease help

Upvotes: 0

Views: 754

Answers (1)

Sector95
Sector95

Reputation: 641

Pushing the ViewAdapter into it's own thread shouldn't be necessary. And actually, in this case, since you want to do some processing on each row, I would abandon the use of a CursorAdapter altogether. I find that the CursorAdapter is really only useful in cases where the data returned by the database is in a ready-to-"digest" form for the ListView (ie. raw text).

Instead, I would use the AsyncTask to load all of the data from the database and process it in one swoop, load the results into a custom object, then build an ArrayAdapter that utilizes the custom objects to display.

Custom class object:

public class ImageObject {
    private String text;
    private String path;
    private Bitmap image;

    public ImageObject(String text, String path) {
        this.text = text;
        this.path = path;
    }

    //Getters and setters for the class variables.
}

The workflow I picture would be as follows:

  1. AsyncTask connects to database, runs query, and sifts through the results placing each row into an ArrayList of ImageObjects.
  2. On each row, it executes the File code you have above, and places the Bitmap into the ImageObject.
  3. AsyncTask returns the ArrayList<ImageObject>
  4. The ArrayList<ImageObjects> is then passed into a custom ArrayAdapter and the data sits in it's final form, ready to be displayed.

Hopefully that makes sense, let me know if you have questions!

Upvotes: 2

Related Questions