为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

湖上湖 2023-07-13 15:34:45
我有两项活动:MainActivity和Activity2。MainActivity只是通过Intent打开第二个。要返回MainActivity,Activity2我按“后退”按钮。当我执行这些步骤时,应用程序崩溃:打开应用程序:MainActivity出现启动Intent:Activity2出现按“返回”按钮:MainActivity出现启动Intent:我的应用程序由于此错误而崩溃:IllegalArgumentException:无法绘制回收的位图MainActivity.java:Intent intent = new Intent(this, Activity2.class); startActivity(intent);Activity2.java:@Overridepublic void onBackPressed() {    super.onBackPressed();}@Overrideprotected 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版本有什么区别吗?或者我遗漏/错误的东西?
查看完整描述

3 回答

?
翻翻过去那场雪

TA贡献2065条经验 获得超13个赞

尝试改变你的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();

}

查看完整回答
反对 回复 2023-07-13
?
森栏

TA贡献1810条经验 获得超5个赞

根据回收文件

位图被标记为“死”,这意味着如果调用 getPixels() 或 setPixels() 它将抛出异常,并且不会绘制任何内容。此操作无法逆转,因此仅当您确定该位图不再使用时才应调用它。

我看不到你如何将 your 分配bitmaps给 your ImageView,但我假设当你在位图被使用后再次启动意图时,你正在尝试重用位图recycled。我只在使用时遇到异常android:src=。如果我ImageView使用以下内容设置位图oncreate,它在您列出的所有目标上运行良好,不会引发异常。

imageView.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.lake_park));
查看完整回答
反对 回复 2023-07-13
?
喵喔喔

TA贡献1735条经验 获得超5个赞

实际上我认为你不必手动执行此操作。

如果 Activity2 只有 1 个图像并且已经调整大小,我认为如果您确实面临内存问题,回收不会有太大帮助。

并且根据该文档,仅建议API级别低于10的用户使用recycle(),并且用户的比例很小。 On Android 2.3.3 (API level 10) and lower, using recycle() is recommended. 

我想推荐使用第三方图像库,因为它们可以让您免于做这些无意义的事情,让您专注于应用程序更重要的部分。


查看完整回答
反对 回复 2023-07-13
  • 3 回答
  • 0 关注
  • 125 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信