Question

I have been trying to query for all images on sd card through MediaStore content provider and display their thumbnail on a GridView.

However, if i load the image thumbnail on the main thread, the scrolling gets incredibly slow...

So i tried to load the bitmap through asynctasks: Scrolling performance got better, but now the grid items keep reloading their thumbnail until it gets the correct bitmap...

Here is my asynctask, which loads the bitmaps:

package x.y;

import java.lang.ref.WeakReference;

import android.content.ContentResolver;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory.Options;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.widget.ImageView;

public class ImageThumbnailLoader extends AsyncTask<Long, Void, Bitmap> {

    private final Options mOptions;

    private WeakReference<ImageView> mImageViewWeakReference;
    private ContentResolver mContentResolver;

        public ImageThumbnailLoader(ImageView imageView,
                ContentResolver cr) {
        mContentResolver = cr;
        mImageViewWeakReference = new WeakReference<ImageView>(imageView);
        mOptions = new Options();
        mOptions.inSampleSize = 4;
    }



    @Override
    protected Bitmap doInBackground(Long... params) {
        Bitmap result;
            result = MediaStore.Images.Thumbnails.getThumbnail(
                    mContentResolver, params[0],
                    MediaStore.Images.Thumbnails.MINI_KIND, mOptions);
        return result;
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        super.onPostExecute(result);
            if (mImageViewWeakReference != null
                    && mImageViewWeakReference.get() != null)
                mImageViewWeakReference.get().setImageBitmap(result);
    }

}

And here is my custom cursor adapter:

package x.y;

import android.content.Context;
import android.database.Cursor;
import android.graphics.BitmapFactory.Options;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ImageView;

public class MediaCursorAdapter extends CursorAdapter {

    private LayoutInflater mInflater;
    private final static int mColumnID = 0;
    private Options mOptions;

    public MediaCursorAdapter(Context context, Cursor c) {
        super(context, c);

        mInflater = LayoutInflater.from(context);
        mOptions = new Options();
        mOptions.inSampleSize = 4;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {

        ViewHolder holder = (ViewHolder) view.getTag();
        ImageThumbnailLoader imageLoader = new ImageThumbnailLoader(holder.thumbImg,
                context.getContentResolver());
        imageLoader.execute(cursor.getLong(mColumnID));
//      holder.thumbImg.setImageBitmap(MediaStore.Images.Thumbnails.getThumbnail(
//                  context.getContentResolver(), cursor.getLong(mColumnID),
//                  MediaStore.Images.Thumbnails.MINI_KIND, mOptions));
        Log.i("Prototype", "bindView : " + cursor.getPosition());
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        Log.i("Prototype", "newView : " + cursor.getPosition());
        View view = mInflater.inflate(R.layout.grid_item, null);
        ViewHolder holder = new ViewHolder(view);
        view.setTag(holder);
        return view;
    }


    private static class ViewHolder {
        ImageView thumbImg, dragImg;

        ViewHolder(View base) {
            thumbImg = (ImageView) base.findViewById(R.id.thumbImage);
            dragImg = (ImageView) base.findViewById(R.id.dragImage);
        }
    }

}

I query the cursor with this code and send it to the adapter:

query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[] { MediaStore.Images.Media._ID,
            MediaStore.Images.Media.DATA }, null, null,
    MediaStore.Images.Media._ID);

Looks like the bindview() on my custom cursor adapter gets called more often than it is supposed to... Anyone knows how can i make the images on my gridview stop reloading while mantaining the scrolling performance??

Thanks in advance.

Was it helpful?

Solution

Problem solved, had to check if image at the start of async task was the same as the image at the end of it, on onPostExecute().

new bindView:

@Override
    public void bindView(View view, Context context, Cursor cursor) {

        ViewHolder holder = (ViewHolder) view.getTag();
        holder.thumbImg.setId(cursor.getPosition());
        ImageThumbnailLoader imageLoader = new ImageThumbnailLoader(holder.thumbImg,
            context.getContentResolver());
        imageLoader.execute(cursor.getLong(mColumnID));
    Log.i("Prototype", "bindView : " + cursor.getPosition());
    }

new Async:

public class ImageThumbnailLoader extends AsyncTask<Long, Void, Bitmap> {

    private final Options mOptions;

    private WeakReference<ImageView> mImageViewWeakReference;
    private ContentResolver mContentResolver;
    private int mPosition;


        public ImageThumbnailLoader(ImageView imageView,
            ContentResolver cr) {
        mContentResolver = cr;
        mImageViewWeakReference = new WeakReference<ImageView>(imageView);
        mOptions = new Options();
        mOptions.inSampleSize = 4;
        mPosition = imageView.getId();
    }



    @Override
    protected Bitmap doInBackground(Long... params) {
        Bitmap result;
            result = MediaStore.Images.Thumbnails.getThumbnail(
                mContentResolver, params[0],
                MediaStore.Images.Thumbnails.MINI_KIND, mOptions);
        return result;
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        super.onPostExecute(result);
            if (mImageViewWeakReference != null
                    && mImageViewWeakReference.get() != null
                        && mPosition == mImageViewWeakReference.get().getId())
                mImageViewWeakReference.get().setImageBitmap(result);
    }

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top