我一直试图通过MediaStore内容提供商查询SD卡上的所有图片,并在GridView上显示他们的缩略图。
但是,如果我在主线程上加载图像缩略图,滚动速度会非常慢......
所以我试图通过asynctasks加载位图: 滚动性能变得更好,但现在网格项不断重新加载缩略图,直到它获得正确的位图...
这是我的asynctask,它加载位图:
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);
}
}
这是我的自定义游标适配器:
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);
}
}
}
我使用此代码查询游标并将其发送到适配器:
query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[] { MediaStore.Images.Media._ID,
MediaStore.Images.Media.DATA }, null, null,
MediaStore.Images.Media._ID);
看起来我的自定义游标适配器上的bindview()被调用的次数比它应该更频繁...任何人都知道如何让我的gridview上的图像停止重新加载,同时保持滚动性能?
提前致谢。
答案 0 :(得分:7)
问题解决后,必须检查异步任务开始时的图像是否与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());
}
新的异步:
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);
}
}