猿问

如果我在 onDestroy() 内调用 recycle() ,“无法绘制回收的位图”

我有两项活动:MainActivityActivity2

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

要返回MainActivityActivity2我按“后退”按钮。

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

  • 打开应用程序:MainActivity出现

  • 启动Intent:Activity2出现

  • 按“返回”按钮:MainActivity出现

  • 启动Intent:我的应用程序由于此错误而崩溃:

    IllegalArgumentException:无法绘制回收的位图

MainActivity.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;

}

由于应用程序使用高分辨率图像(已使用BitmapFactory和进行调整inSampleSize),为了避免内存泄漏,我recycle()在该onDestroy()方法中调用。

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

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

现在我有点担心我所学到的东西,因为如果我删除该recycle()错误就不会再发生。

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

  • 问题出在活动堆栈上吗?

  • GC 尝试释放位图内存是否太晚了?在这种情况下,如何彻底销毁 Activity 及其所有内容?

  • 这两个Android版本有什么区别吗?

  • 或者我遗漏/错误的东西?


湖上湖
浏览 126回答 3
3回答

翻翻过去那场雪

尝试改变你的onDestroy方法如下@Overrideprotected 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();}

森栏

根据回收文件位图被标记为“死”,这意味着如果调用 getPixels() 或 setPixels() 它将抛出异常,并且不会绘制任何内容。此操作无法逆转,因此仅当您确定该位图不再使用时才应调用它。我看不到你如何将 your 分配bitmaps给 your ImageView,但我假设当你在位图被使用后再次启动意图时,你正在尝试重用位图recycled。我只在使用时遇到异常android:src=。如果我ImageView使用以下内容设置位图oncreate,它在您列出的所有目标上运行良好,不会引发异常。imageView.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.lake_park));

喵喔喔

实际上我认为你不必手动执行此操作。如果 Activity2 只有 1 个图像并且已经调整大小,我认为如果您确实面临内存问题,回收不会有太大帮助。并且根据该文档,仅建议API级别低于10的用户使用recycle(),并且用户的比例很小。 On Android 2.3.3 (API level 10) and lower, using recycle() is recommended. 我想推荐使用第三方图像库,因为它们可以让您免于做这些无意义的事情,让您专注于应用程序更重要的部分。
随时随地看视频慕课网APP

相关分类

Java
我要回答