【问题标题】:Android ICS bitmap recyclingAndroid ICS 位图回收
【发布时间】:2012-07-20 09:13:26
【问题描述】:

我在onDestroy 中使用以下代码来回收大位图以快速恢复内存。如果我不这样做,应用程序将在屏幕旋转几次后因 OutOfMemory 错误而崩溃。 Android 在处理内存方面很糟糕。

ImageView imgBG = (ImageView)findViewById(R.id.mainBG);
if (imgBG != null)
{
    ((BitmapDrawable)imgBG.getDrawable()).getBitmap().recycle();
    imgBG.setImageDrawable(null);
}
System.gc();

不幸的是,ICS 中的情况发生了变化。他们开始缓存资源并回收位图实际上回收了缓存中的位图。 Android 不够聪明,无法弄清楚它,它试图在未来使用回收的位图,结果是:

java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@40f44390
at android.graphics.Canvas.throwIfRecycled(Canvas.java:1047)
at android.graphics.Canvas.drawBitmap(Canvas.java:1151)
at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:400)
at android.widget.ImageView.onDraw(ImageView.java:973)
at android.view.View.draw(View.java:11014)
at android.view.ViewGroup.drawChild(ViewGroup.java:3186)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2788)
at android.view.ViewGroup.drawChild(ViewGroup.java:3184)
[...]

所以这就是问题所在。如果我回收它,它将在 ICS 上崩溃。如果我不这样做,该应用程序将耗尽内存。我该怎么办?真正有效的释放内存的正确方法是什么?

【问题讨论】:

  • 我认为这种缓存(共享)即使在 Android 2.3 中也已完成,也许只是没有那么激进。然而,据我所知,它用于 XML 定义的位图。您是否尝试通过 decodeBitmap 加载位图,然后设置为视图?在这种情况下,希望 Android 不会使用系统缓存。让我知道它是怎么回事,因为我也有类似的问题,期待您的体验。

标签: android bitmap out-of-memory android-4.0-ice-cream-sandwich recycle


【解决方案1】:

试试这个:

ImageView imgBG = (ImageView)findViewById(R.id.mainBG);
if (imgBG != null)
{
    BitmapDrawable drawable = ((BitmapDrawable)imgBG.getDrawable()).getBitmap();
    imgBG.setImageDrawable(null);
    drawable.recycle();
}
System.gc();

【讨论】:

  • 这正是我正在做的事情,我的问题解释了为什么这种方法现在是错误的。您不能回收位图。
  • 根据抛出的异常:UI更新可能有不同的线程?这是要求回收的位图。这就是为什么我先将位图存储为可绘制,设置为空,然后回收。
  • 停止猜测,阅读我的问题。它解释了 recycle() 失败的原因以及为什么这种方法是错误的。
猜你喜欢
  • 2011-12-22
  • 2012-08-09
  • 2012-10-31
  • 2015-07-18
  • 1970-01-01
  • 1970-01-01
  • 2011-04-18
  • 1970-01-01
  • 2012-07-10
相关资源
最近更新 更多