2011-08-10 42 views
38

我有这样的事情:回收的ImageView位图

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的画布想要绘制循环位图的异常。

什么是回收已经被放在ImageView上的图像的位图的方式?

Thanksb

+0

imageView.setImageBitmap(bm);并在该块结束..没有其他线路。 –

回答

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)); 
} 
+0

在他的情况下,也许应该在他再次调用'setImageBitmap()'之前完成。 – user802421

+0

我无法访问使用ImageView的活动,我只是实现自定义ImageView,所以我认为ImageView类本身具有一些在C++中作为析构函数的机制,或者知道该ImageView的实例不是使用了.. –

+0

我必须为所有图像做这个或只为大的。我不能只将其他图像分配给图像视图? – hasan83

2

在你的所有ImageView s,它不应该扔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兆,如果我正确计算)。您可以:

  • 让你的位图小
  • 削减使用大量的内存
+0

问题是,即使我回收利用.createBitmap创建的位图,每次该方法结束时堆都会增长。我回收它后,检查是否可以 - 不会,堆积增长。所以我想这是泄漏.. –

+0

12Mpx!= 12MB。它可能需要更多的内存,而不仅仅是12MB。 12Mpx位图可能需要超过35MB。 –

-1

不要创建图像比你需要的在任一周时间大其他的东西。堆的限制旨在防止您挂断自己并完全接管设备的有限内存。

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

1

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