Recycle ImageView's Bitmap
Solution 1
In your onDestroy method you could try something like this:
ImageView imageView = (ImageView)findViewById(R.id.my_image);
Drawable drawable = imageView.getDrawable();
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
Bitmap bitmap = bitmapDrawable.getBitmap();
bitmap.recycle();
}
The cast should work since setImageBitmap is implemented as
public void setImageBitmap(Bitmap bm) {
setImageDrawable(new BitmapDrawable(mContext.getResources(), bm));
}
Solution 2
If you set the same bitmap object on all your ImageView
s, it shouldn't throw an OutOfMemoryError
. Basically, this should work:
WeakReference<Bitmap> bm = new WeakReference<Bitmap>(Bitmap.createBitmap(3000 + 3000, 2000, Bitmap.Config.ARGB_8888));
Canvas canvas = new Canvas(bm.get());
canvas.drawBitmap(firstBitmap, 0, 0, null);
canvas.drawBitmap(bm, firstBitmap.getWidth(), 0, null);
imageView1.setImageBitmap(bm.get());
imageView2.setImageBitmap(bm.get());
imageView3.setImageBitmap(bm.get());
imageView4.setImageBitmap(bm.get());
imageView5.setImageBitmap(bm.get());
// ...
If this doesn't work, it simply means your bitmap is too large (6000x2000 pixels is about 12 megabytes, if I calculated right). You can either:
- make your bitmap smaller
- cut down on other stuff that use a lot of memory
Solution 3
Devconsole's answer is great, but you can also store all bitmap objects in list like member of your class, and then recycle them in cycle when the onDestroy() method of activity (or some other release lifecycle method of component where you use bitmap) will be called.
Peter Olsbourg
Updated on February 17, 2020Comments
-
Peter Olsbourg about 4 years
I have something like this:
Bitmap.Config conf = Bitmap.Config.ARGB_8888; WeakReference<Bitmap> bm = new WeakReference<Bitmap>(Bitmap.createBitmap(3000 + 3000, 2000, conf)); Canvas canvas = new Canvas(bm.get()); canvas.drawBitmap(firstBitmap, 0, 0, null); canvas.drawBitmap(bm, firstBitmap.getWidth(), 0, null); imageView.setImageBitmap(bm);
And I apply this on more than 10 imageView's which are created one by one. Whenever I create new ImageView, I want to recycle the 'bm' object from the first one, cause this code up there, causes my heap to grow more and more and then throw OutOfMemoryError, so I do:
bm.recycle()
right after I set the Bitmap (bm) to the imageView object. This causes exception that the ImageView's canvas wants to draw recycled Bitmap.
What is the way to recycle a Bitmap that has already been put as image on ImageView?
Thanksb
-
user802421 over 12 yearsIn his case, maybe it should be done right before he call
setImageBitmap()
again. -
Peter Olsbourg over 12 yearsI don't have access to the Activity where the ImageView is used, I just implement custom ImageView, so I thought the ImageView class itself has some mechanism as destructor in C++ or any signal to know that the very instance of that ImageView is not used anymore..
-
Peter Olsbourg over 12 yearsThe thing is that even though I recycle the Bitmap created with .createBitmap, the heap grows everytime this methods ends. I recycle it right after to check if it's ok - nope, the heap grows. So I suppose this is the leak..
-
hasan over 10 yearsDo I have to do this for all images or just for large ones. can't I just assign another image to the image view?
-
diego nunes almost 9 years12Mpx != 12MB. It is probably taking a lot more memory than just 12MB. A 12Mpx Bitmap can take more than 35MB.