回收ImageView的位图

时间:2011-08-10 10:09:19

标签: java android memory-leaks bitmap

我有这样的事情:

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);

我将这个应用于10个以上逐个创建的imageView。 每当我创建新的ImageView时,我想从第一个回收'bm'对象,导致这个代码在那里,导致我的堆越来越多,然后抛出 OutOfMemoryError ,所以我这样做:

bm.recycle()

我将Bitmap(bm)设置为imageView对象后。 这会导致ImageView的画布想要绘制回收的Bitmap。

回收已在ImageView上作为图像放置的位图的方法是什么?

Thanksb

4 个答案:

答案 0 :(得分:55)

在你的onDestroy方法中你可以试试这样的东西:

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();
}

由于setImageBitmap实现为

,因此强制转换应该有效
public void setImageBitmap(Bitmap bm) {
    setImageDrawable(new BitmapDrawable(mContext.getResources(), bm));
}

答案 1 :(得分:2)

如果在所有ImageView上设置相同的位图对象,则不应抛出OutOfMemoryError。基本上,这应该工作:

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());
// ...

如果这不起作用,它只是意味着你的位图太大(6000x2000像素约为12兆字节,如果我计算正确的话)。你可以:

  • 缩小您的位图
  • 减少使用大量内存的其他东西

答案 2 :(得分:1)

Devconsole的答案很棒,但您也可以将所有位图对象存储在列表中,就像您的类成员一样,然后在onDestroy()方法的活动(或其他一些发布生命周期方法)中循环它们将调用您使用位图的组件。

答案 3 :(得分:-1)

不要在任何时候创建大于您需要的图像。堆限制旨在防止您自行挂起并完全接管设备的有限内存。

如果由于计划放大而需要更多细节,请在缩放时重新渲染图像的那部分,但不包括您未查看的部分。