java - "Cannot draw recycled bitmaps"如果我在 onDestroy() 中调用 recycle()

标签 java android exception bitmap garbage-collection

我有两个 Activity :MainActivityActivity2

MainActivity 只需通过 Intent 打开第二个。

要从 Activity2 返回到 MainActivity,我按“后退”按钮。

当我执行这些步骤时,应用程序崩溃了:

  • 打开应用程序:MainActivity 出现
  • 启动 Intent:Activity2 出现
  • 按下“后退”按钮:MainActivity 出现
  • 启动Intent:我的应用程序因为这个错误而崩溃:

    IllegalArgumentException: Cannot draw recycled bitmaps

主要 Activity .java:

Intent intent = new Intent(this, Activity2.class);
startActivity(intent);

Activity2.java:

@Override
public void onBackPressed() {
    super.onBackPressed();
}

@Override
protected void onDestroy() {
    super.onDestroy();

    for(Map.Entry<Integer, ImageView> entry : mapImageViews.entrySet()) {
        ImageView imageView = entry.getValue();
        Drawable drawable = imageView.getDrawable();
        if (drawable instanceof BitmapDrawable) {
            BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
            Bitmap bitmap = bitmapDrawable.getBitmap();
            if(bitmap != null) {
                bitmap.recycle();
            }
            bitmapDrawable = null;
            bitmap = null;
        }
        imageView.setOnClickListener(null);
        imageView.setImageDrawable(null);
        imageView.setImageBitmap(null);
        imageView = null;
        drawable = null;
    }
    mapImageViews.clear();
    mapImageViews = null;
}

由于应用程序使用高分辨率图像(已使用 BitmapFactoryinSampleSize 进行适配),为了避免内存泄漏,我调用了 recycle() onDestroy() 方法。

正如我通过阅读大量 SO 答案和在 Web 上了解到的那样,在位图上调用 recycle() 可以让它们尽早被垃圾回收。

但许多其他帖子建议不要调用 recycle(),或者至少建议仅当您确定 Activity 中不再需要位图时才这样做,即 onDestroy() 方法。

现在我有点担心我对它的了解,因为如果我删除 recycle() 错误就不会再发生。

错误发生在 Android 4.4.2 设备上,但不会发生在 Android 6.0 设备和 Nexus 7 上>(Android 5.1.1)。

  • 是关于 Activity 堆栈的问题吗?
  • GC 试图释放位图的内存是否为时已晚?在这种情况下,如何彻底销毁 Activity 及其所有内容?
  • 这两个安卓版本有什么区别吗?
  • 或者我遗漏了什么/错了什么?

最佳答案

尝试像下面这样改变你的onDestroy方法

@Override
protected void onDestroy() {
    for(Map.Entry<Integer, ImageView> entry : mapImageViews.entrySet()) {
        ImageView imageView = entry.getValue();
        Drawable drawable = imageView.getDrawable();
        if (drawable instanceof BitmapDrawable) {
            BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
            Bitmap bitmap = bitmapDrawable.getBitmap();
            if(bitmap != null) {
                bitmap.recycle();
            }
            bitmapDrawable = null;
            bitmap = null;
        }
        imageView.setOnClickListener(null);
        imageView.setImageDrawable(null);
        imageView.setImageBitmap(null);
        imageView = null;
        drawable = null;
    }
    mapImageViews.clear();
    mapImageViews = null;

    super.onDestroy();
}

另见:How to recycle and reuse images以一种有效的方式。

关于java - "Cannot draw recycled bitmaps"如果我在 onDestroy() 中调用 recycle(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57793369/

相关文章:

Android:设置一个按钮做几件事

c++ - 在 C++ 中捕获 Python 异常

Java GUI Jframe 异常处理

java - PircBotX 类型的 connect() 方法不可见

java - 为 Galaxy Gear 制作应用程序

android - 使用改造调用添加自签名证书

java - 是否可以使用 JUnit Rule ExpectedException 访问异常 "catched"的实例?

java - 在Java中解析文本文件的最快方法

java - 断电期间文件操作如何执行

android - fragment 中的 getMapAsync()