In Android 4.1 a, to me, seemingly strange error occurs in our app. In the app a custom adapter extending BaseAdapter is attached to a Gallery widget. When scrolling fast left-to-right and vice versa I get a FC with the exception message:
java.lang.IllegalArgumentException: Cannot draw recycled bitmap
Code for the getView(..) method is as follows:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null){
// View is not recycled. Inflate the layout.
LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.gallery_image, parent, false);
viewHolder = new ViewHolder();
viewHolder.image = (ImageView) convertView.findViewById(R.id.gallery_image);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder)convertView.getTag();
viewHolder.image.setImageDrawable(null);
}
imageLoader.displayImage(images.get(position).getFilename(),
images.get(position).getUrlThumbnail(),
viewHolder.image,
Math.round(BitmapUtil.convertDpToPixel(400f, context)),
Math.round(BitmapUtil.convertDpToPixel(400f, context)));
return convertView;
}
I guess I should null the ImageView somewhere, but I cannot get it to work correctly. ImageLoader is a (quite) simple class for loading the images – either from LruCache, disk/sdcard or fetch it remotely.
It turns out that this error was caused by calling
oldBitmap.recycle()in theentryRemoved(..)method in my class overriding LruCache. As the bitmap might still be attached to the ImageView callingrecycle()will cause trouble.If I understand correctly: LruCache’s cache size will be set in its constructor. When the number of items exceeds this size the objects will be eligible for garbage collection, which will happen when the bitmap is no longer associated with an ImageView.
A lot of examples and tutorials around the web suggest that
recycle()should be called inentryRemoved(..), but from what I can see this is wrong.