Android gridview图像缓存,滚动图像在替换前重复

Android gridview图像缓存,滚动图像在替换前重复,android,performance,android-imageview,android-gridview,android-adapter,Android,Performance,Android Imageview,Android Gridview,Android Adapter,我有GridView和ImageView,它们是从图库的图像缩略图加载的。我从一个类中加载这些缩略图,在这个类中,我调用了一个带有图像id和imageview的方法,该方法将位图设置为传递的imageview。在这里,它工作正常,但在抛出网格视图时线程暂停 我这里的问题是它在滚动时会暂停,但在从上到下滚动时,图像会在gridview中重复。我想不出确切的问题。帮帮我。谢谢 下面是我如何设置暂停: imagegrid.setOnScrollListener(new AbsListView.OnSc

我有GridView和ImageView,它们是从图库的图像缩略图加载的。我从一个类中加载这些缩略图,在这个类中,我调用了一个带有图像id和imageview的方法,该方法将位图设置为传递的imageview。在这里,它工作正常,但在抛出网格视图时线程暂停

我这里的问题是它在滚动时会暂停,但在从上到下滚动时,图像会在gridview中重复。我想不出确切的问题。帮帮我。谢谢

下面是我如何设置暂停:

imagegrid.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView absListView, int scrollState) {
                // Pause fetcher to ensure smoother scrolling when flinging
                if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
                    bitmapFromId.setPauseWork(true);
                } else {
                    bitmapFromId.setPauseWork(false);
                }
            }

            @Override
            public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            }
        });
以下是我在grdiview适配器中的get视图:

public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                holder = new ViewHolder();
                convertView = mInflater.inflate(R.layout.galleryitem, null);
                holder.imageview = (ImageView) convertView.findViewById(R.id.thumbImage);
                holder.checkbox = (CheckBox) convertView.findViewById(R.id.itemCheckBox);

                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            ImageItem item = images.get(position);
            holder.checkbox.setId(position);
            holder.imageview.setId(position);
            holder.checkbox.setOnClickListener(new OnClickListener() {

                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    CheckBox cb = (CheckBox) v;
                    int id = cb.getId();
                    if (images.get(id).selection) {
                        cb.setChecked(false);
                        images.get(id).selection = false;
                    } else {
                        cb.setChecked(true);
                        images.get(id).selection = true;
                    }
                }
            });
            holder.imageview.setOnClickListener(new OnClickListener() {

                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    int id = v.getId();
                    ImageItem item = images.get(id);
                    Intent intent = new Intent();
                    intent.setAction(Intent.ACTION_VIEW);
                    final String[] columns = { MediaStore.Images.Media.DATA };
                    Cursor imagecursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                            columns, MediaStore.Images.Media._ID + " = " + item.id, null, MediaStore.Images.Media._ID);
                    if (imagecursor != null && imagecursor.getCount() > 0) {
                        imagecursor.moveToPosition(0);
                        String path = imagecursor.getString(imagecursor
                                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
                        File file = new File(path);
                        imagecursor.close();
                        intent.setDataAndType(Uri.fromFile(file), "image/*");
                        startActivityForResult(intent, VIEW_IMAGE);
                    }
                }
            });

            holder.imageview.setLayoutParams(mImageViewLayoutParams);

            // Check the height matches our calculated column width
            if (holder.imageview.getLayoutParams().height != mItemHeight) {
                holder.imageview.setLayoutParams(mImageViewLayoutParams);
            }

            bitmapFromId.DisplayImage(item.id, holder.imageview);
            // holder.imageview.setImageBitmap(item.img);
            holder.checkbox.setChecked(item.selection);
            return convertView;
        }
我的位图加载程序类:

public class BitmapFromId {

    MemoryCache memoryCache = new MemoryCache();
    FileCache fileCache;
    private Map<ImageView, String> imageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
    ExecutorService executorService;
    Context context;
    Handler handler = new Handler();// handler to display images in UI thread

    Resources mResources;
    private static final int FADE_IN_TIME = 400;

    private final Object mPauseLock = new Object();

    private boolean mPaused = false;

    public BitmapFromId(Context context) {
        fileCache = new FileCache(context);
        executorService = Executors.newFixedThreadPool(5);
        this.context = context;
        mResources = context.getResources();
    }

    public void DisplayImage(long id, ImageView imageView) {

        Bitmap bitmap = null;
        String _id = String.valueOf(id);
        imageViews.put(imageView, _id);
        bitmap = memoryCache.get(_id);
        if (bitmap != null)
            imageView.setImageBitmap(bitmap);
        else {
            queuePhoto(_id, imageView);
            imageView.setBackgroundResource(R.drawable.empty_photo);
        }
    }

    private void queuePhoto(String id, ImageView imageView) {
        PhotoToLoad p = new PhotoToLoad(id, imageView);
        executorService.submit(new PhotosLoader(p));
    }

    // decodes image
    private Bitmap getImageFromId(String id) {
        Bitmap bitmap;

        long _id = Long.parseLong(id);
        final String[] columns = { MediaStore.Images.Media.DATA };
        final String orderBy = MediaStore.Images.Media._ID;
        Cursor imagecursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns,
                MediaStore.Images.Media._ID + " = " + _id + "", null, orderBy);
        int count = imagecursor.getCount();
        for (int i = 0; i < count; i++) {
            imagecursor.moveToPosition(i);
            bitmap = MediaStore.Images.Thumbnails.getThumbnail(context.getContentResolver(), _id,
                    MediaStore.Images.Thumbnails.MICRO_KIND, null);
            return bitmap;
        }
        imagecursor.close();
        return null;

    }

    // Task for the queue
    private class PhotoToLoad {
        public String id;
        public ImageView imageView;

        public PhotoToLoad(String _i, ImageView i) {
            id = _i;
            imageView = i;
        }
    }

    class PhotosLoader implements Runnable {
        PhotoToLoad photoToLoad;

        PhotosLoader(PhotoToLoad photoToLoad) {
            this.photoToLoad = photoToLoad;
        }

        @Override
        public void run() {
            try {
                if (imageViewReused(photoToLoad))
                    return;
                Bitmap bmp = getImageFromId(photoToLoad.id);
                memoryCache.put(photoToLoad.id, bmp);
                if (imageViewReused(photoToLoad))
                    return;
                BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);
                handler.post(bd);

                synchronized (mPauseLock) {
                    while (mPaused) {
                        try {
                            mPauseLock.wait();
                        } catch (InterruptedException e) {
                        }
                    }
                }

            } catch (Throwable th) {
                th.printStackTrace();
            }
        }
    }

    boolean imageViewReused(PhotoToLoad photoToLoad) {
        String tag = imageViews.get(photoToLoad.imageView);
        if (tag == null || !tag.equals(photoToLoad.id))
            return true;
        return false;
    }

    // Used to display bitmap in the UI thread
    class BitmapDisplayer implements Runnable {
        Bitmap bitmap;
        PhotoToLoad photoToLoad;

        public BitmapDisplayer(Bitmap b, PhotoToLoad p) {
            bitmap = b;
            photoToLoad = p;

        }

        public void run() {
            if (imageViewReused(photoToLoad))
                return;
            if (bitmap != null) {

                // Load the image fetched:
                final TransitionDrawable td = new TransitionDrawable(new Drawable[] {
                        new ColorDrawable(android.R.color.transparent), new BitmapDrawable(mResources, bitmap) });

                photoToLoad.imageView.setImageDrawable(td);
                td.startTransition(FADE_IN_TIME);

            } else
                photoToLoad.imageView.setImageDrawable(null);
        }
    }

    public void clearCache() {
        memoryCache.clear();
        fileCache.clear();
    }

    public void setPauseWork(boolean pauseWork) {
        if (pauseWork) {
            synchronized (mPauseLock) {
                mPaused = true;
            }
        } else {
            synchronized (mPauseLock) {
                mPaused = false;
                mPauseLock.notifyAll();

            }
        }
    }

}
公共类BitmapFromId{
MemoryCache MemoryCache=新的MemoryCache();
文件缓存文件缓存;
private Map ImageView=Collections.synchronizedMap(新的WeakHashMap());
执行服务执行服务;
语境;
Handler=new Handler();//在UI线程中显示图像的处理程序
资源;
专用静态最终积分衰减时间=400;
私有最终对象mPauseLock=新对象();
私有布尔值=false;
公共BitmapFromId(上下文){
fileCache=新的fileCache(上下文);
executorService=Executors.newFixedThreadPool(5);
this.context=上下文;
mResources=context.getResources();
}
public void DisplayImage(长id,ImageView){
位图=空;
String _id=String.valueOf(id);
imageView.put(imageView,_id);
位图=memoryCache.get(_id);
if(位图!=null)
设置图像位图(位图);
否则{
队列照片(_id,imageView);
imageView.setBackgroundResource(R.drawable.empty_photo);
}
}
私有无效队列照片(字符串id,ImageView){
PhotoToLoad p=新的PhotoToLoad(id,imageView);
executorService.submit(新的PhotoLoader(p));
}
//解码图像
私有位图getImageFromId(字符串id){
位图;
long _id=long.parseLong(id);
最终字符串[]列={MediaStore.Images.Media.DATA};
最终字符串orderBy=MediaStore.Images.Media.\u ID;
Cursor imagecursor=context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL\u CONTENT\u URI,列,
MediaStore.Images.Media.\u ID+“=”+\u ID+”,null,orderBy);
int count=imagecursor.getCount();
for(int i=0;i
您可以使用Aquery框架管理所有图像加载/缓存控制机制

这很简单。例如,像这样加载/缓存图像

aq.id(R.id.YourImageViewID).image("http://www.vikispot.com/z/images/vikispot/android-w.png", memCache, fileCache);
见文件