Java 回收图像视图';s位图

Java 回收图像视图';s位图,java,android,memory-leaks,bitmap,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);

我有这样的想法:

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);
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();
}
在我将位图(bm)设置为imageView对象之后。 这会导致ImageView的画布希望绘制循环位图的异常

如何回收已作为图像放在ImageView上的位图


感谢某人在onDestroy方法中,您可以尝试以下方法:

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

如果在所有
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());
// ...
WeakReference bm=新的WeakReference(Bitmap.createBitmap(3000+3000,2000,Bitmap.Config.argb8888));
Canvas Canvas=新画布(bm.get());
drawBitmap(firstBitmap,0,0,null);
drawBitmap(bm,firstBitmap.getWidth(),0,null);
setImageBitmap(bm.get());
setImageBitmap(bm.get());
setImageBitmap(bm.get());
setImageBitmap(bm.get());
setImageBitmap(bm.get());
// ...
如果这不起作用,那就意味着位图太大(如果我计算正确的话,6000x2000像素大约是12兆字节)。您可以:

  • 使位图变小
  • 减少其他占用大量内存的内容

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


如果由于计划放大而需要更详细的信息,则在缩放时以更高的细节重新渲染图像的该部分,不包括您未查看的部分。

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

它位于imageView.setImageBitmap(bm)之后;在这下面,街区就结束了。。没有其他行。在他的情况下,可能应该在他再次调用
setImageBitmap()
之前完成。我没有访问使用ImageView的活动的权限,我只是实现自定义ImageView,因此我认为IVIEVIEW类本身有一些机制,作为C++中的析构函数或任何信号,知道IVIEVIEW的非常实例不再被使用。我必须为所有图像或仅仅是大图像来这样做。我不能将另一个图像分配给图像视图吗?问题是,即使我循环使用.createBitmap创建的位图,每次该方法结束时,堆都会增长。之后我立即循环使用它,检查它是否正常-不,堆会增长。所以我想这就是漏洞了..12Mpx!=12MB。它可能需要比12MB多得多的内存。12Mpx位图可能需要35MB以上的空间。