回收ImageView的位图

发布于 2024-11-28 23:42:34 字数 686 浏览 1 评论 0原文

我有这样的东西:

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

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

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

谢谢b

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

带刺的爱情 2024-12-05 23:42:34

在你的 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));
}

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));
}
情仇皆在手 2024-12-05 23:42:34

如果您在所有 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 兆字节)。您可以:

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

If you set the same bitmap object on all your ImageViews, 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
横笛休吹塞上声 2024-12-05 23:42:34

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

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.

白衬杉格子梦 2024-12-05 23:42:34

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

如果您因为计划放大而需要更多细节,请在缩放时以更高的细节重新渲染图像的该部分,不包括您未查看的部分。

Don't create images larger than you need at any one time. The heap limitations are designed to prevent you from hanging yourself and completely taking over the device's limited memory.

If you need more detail because you plan on zooming in, then re-render that portion of the image with higher detail at zoom time, excluding the portions you aren't viewing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文