Skip to content Skip to sidebar Skip to footer

Android Listview Updating Of Image Thumbnails Using Asynctask Causes View Recycling

I have been trying to get thumbnails to work with an AsyncTask for image files in a ListView. I have been having the common problem of Row Recycling, and thus on scrolling thumbnai

Solution 1:

From this blog post:

What you want to do is running all per-row IO or any heavy CPU-bound routine asynchronously in a separate thread. The trick here is to do that and still comply with ListView‘s recycling behaviour. For instance, if you run an AsyncTask to load a profile picture in the adapter’s getView(), the view you’re loading the image for might be recycled for another position before the AsyncTask finishes. So, you need a mechanism to know if the view hasn’t been recycled once you’re done with the async operation.

One simple way to achieve this is to attach some piece of information to the view that identifies which row is associated with it. Then you can check if the target row for the view is still the same when the async operation finishes. There are many ways of achieving this. Here is just a simplistic sketch of one way you could do it:

public View getView(int position, View convertView,
        ViewGroup parent) {
    ViewHolder holder;

    ...

    holder.position = position;

    newThumbnailTask(position, holder)
            .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);

    return convertView;
}

privatestaticclassThumbnailTaskextendsAsyncTask {
    privateint mPosition;
    private ViewHolder mHolder;

    publicThumbnailTask(int position, ViewHolder holder) {
        mPosition = position;
        mHolder = holder;
    }

    @Overrideprotected Cursor doInBackground(Void... arg0) {
        // Download bitmap here
    }

    @OverrideprotectedvoidonPostExecute(Bitmap bitmap) {
        if (mHolder.position == mPosition) {
            mHolder.thumbnail.setImageBitmap(bitmap);
        }
    }
}

privatestaticclassViewHolder {
    public ImageView thumbnail;
    publicint position;
}

Solution 2:

Using the AsyncTask.THREAD_POOL_EXECUTOR wil end up running multiple threads to fetch the thumnails. There is no order in the way they run or finisch and set the image for the view. When scrolling back and forth you may end up with the wrong images in your views.

I tested the AsyncTask.THREAD_POOL_EXECUTOR and it does lead to the wrong image for some views.

Solution 3:

you can try passing in ListView into your Adapter constructor from your activity (may be even into your async task depends how you want to implement it). and compare the position using getFirstVisiblePosition() and getLastVisiblePosition() against your mPosition

Post a Comment for "Android Listview Updating Of Image Thumbnails Using Asynctask Causes View Recycling"