I’ve attempted to implement the bitmap caching and have got 90% there. I’m using LruCache. I use the item position as the key, which I store in the imageView tag. The cache write happens in onThumbnailDownloaded()

I have modified the getView() method as follows:


if (mCache.contains(Integer.toString(position))) {
return view;



This works nicely but the recycled views cause havoc when scrolling fast back towards the top of the list. If new items become visible and begin downloading, but the user scrolls up before the new items have rendered, previously rendered items get overwritten with the new items.

Inflating a new view each time solves the problem.

Any ideas on what I can do retain the recylced views, but ensure new images are only rendered in their correct position?


Did you ever get it to work?



I had the same problem.
It didn’t occur on original code (without caching) as explained at the end of page 448 because when you recycled an ImageView, you immediately asked for a new download and thus associated the new URL to the ImageView (the token in the requestMap) and then when the original download was finished, the downloaded URL didn’t match with the current URL in the requestMap:

if (requestMap.get(token) != url) return;

So I created a method to invalidate the requestMap entry when using a cached image.
In ThumbnailDownloader:

public void dequeueThumbnail(Token token) { requestMap.remove(token); }

and in getView() of PhotoGalleryFragment:

GalleryItem item = getItem(position); String url = item.getUrl(); Bitmap bitmap = getBitmapFromMemCache(url); if(bitmap == null) { mThumbnailThread.queueThumbnail(imageView, url); } else { mThumbnailThread.dequeueThumbnail(imageView); if (isVisible()) { imageView.setImageBitmap(bitmap); } }