Reputation: 133
I've read a ton of posts about both these errors and can't seem to find a solution that works for me. I have a basic listview activity of animals. When you click on an item in the list, it opens the AnimalViewActivity and displays a simple png image inside an ImageView.
Here's where I set the image for the ImageView:
public void getImage() {
String imageName = myService.yourAnimals.get(key).getType();
System.out.println(imageName);
Resources res = getResources();
int resourceId = res.getIdentifier(imageName, "drawable", getPackageName() );
Drawable drawable = res.getDrawable( resourceId );
image.setImageDrawable( drawable );
}
Then when I leave AnimalViewActivity to return to the listview activity, I do this:
@Override
protected void onDestroy() {
super.onDestroy();
//((BitmapDrawable)image.getDrawable()).getBitmap().recycle();
image.getDrawable().setCallback(null);
//System.gc();
System.out.println("Destroy image!");
}
If I uncomment the recycle() line, I get the "cannot draw recycled bitmaps" error. If I leave it how it is, I get the outofmemoryerror for bitmapfactory.
java.lang.IllegalArgumentException: Cannot draw recycled bitmap OR java.lang.OutOfMemoryError android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
Either one of these errors occur after I've opened the ViewAnimalActivity about 20 times and the app crashes. The only thing that seems to work forever is System.gc() , but I know that is not a good solution.
I'm testing it in android4.1, but the minSDK is set to android3.0
I read that the javaVM error for bitmap recycling was fixed in 3.0?
For some reason, garbage collection is not happening fast enough without explicitly calling the gc. These images are small, mostly between 100-300kB.
Any ideas?
EDIT:
It seems happier with
image.setImageDrawable( null );
I think I tried this before when I still had it set on Android2.2, but Android3.0 is happy with it so far.
Upvotes: 3
Views: 2480
Reputation: 103
Why don't you try setting the drawable to null first, then recycle it? The problem is probably because the drawable is still on the image when you recycled it, thus causing the "cannot draw recycled bitmaps error". If you set that to null first, thereby setting the actual ImageView (or whatever it is that you're using) to null, then recycling it, that will probably solve your issue.
Edit: WOOPS! I totally forgot if you set a drawable to null, then you can't retrieve the bitmap you're trying to recycle. Try assigning that to a variable first, then recycle it.
Upvotes: 0
Reputation: 5578
The documentation for recycle() states explicitly that it is for "advanced use". It's more important to set the references to null, actually.
This is an advanced call, and normally need not be called, since the normal GC process will free up this memory when there are no more references to this bitmap.
There is, in addition, the possibility to look if a Bitmap has been recycled before drawing it. (post your logcat to see where you're having the error. You could add code to verify if the Bitmap has been recycled and re-load it).
Overall, I think you'd best look at the Android Training Lessons that tell you how to display Bitmaps efficiently.
Upvotes: 3