我构建了一个自定义视图(类似于网格视图),可以显示许多图像,因此回收Bitmaps是此应用程序的必需品。我正在使用Lru缓存(在下面实现)来处理Bitmap回收。当我在Android 2.3设备上测试它(并快速滚动)时,我收到以下错误消息,应用程序崩溃了。在弄清楚如何复制bug之后,我在Android 4.0上进行了测试,它运行得很好。
06-27 10:57:48.420: E/AndroidRuntime(14255): FATAL EXCEPTION: main
06-27 10:57:48.420: E/AndroidRuntime(14255): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@407fc6b8
06-27 10:57:48.420: E/AndroidRuntime(14255): at android.graphics.Canvas.throwIfRecycled(Canvas.java:955)
06-27 10:57:48.420: E/AndroidRuntime(14255): at android.graphics.Canvas.drawBitmap(Canvas.java:1044)
06-27 10:57:48.420: E/AndroidRuntime(14255): at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:325)
06-27 10:57:48.420: E/AndroidRuntime(14255): at android.widget.ImageView.onDraw(ImageView.java:872)
etc etc
我跟踪了这个错误,结果是在将位图设置为ImageView之前,我检查了Bitmap是否被回收。但是,Bitmap在该步骤和draw()步骤之间被回收,从而导致错误。
这是我的缓存:
sLruCache = new LinkedHashMap(capacity / 2, 0.75f, true) { private static final long serialVersionUID = -7282875042976381535L; @Override protected boolean removeEldestEntry(LinkedHashMap.Entry eldest) { if (size() > mCapacity) { return true; } else return false; } public Bitmap remove(Object key) { Bitmap bitmap = super.remove(key); if (bitmap != NULL_BITMAP) { bitmap.recycle(); } return bitmap; }; @Override public void clear() { Set keys = new HashSet(keySet()); for (String key : keys) { Bitmap map = get(key); if (map != NULL_BITMAP) { map.recycle(); } } super.clear(); } };
关于为什么在Android 2.3而不是4.0上会失败的任何想法?
答案 0 :(得分:0)
我有同样的问题。
我必须删除所有Bitmap.recycle()调用。它有时会导致OutOfMemoryException。
因此,我这样做了一个黑客:
// when I need to remove bitmap from cache
if (Build.VERSION.SDK_INT < 9 || Build.VERSION.SDK_INT > 10) {
bmp.recycle();
}
这不是一个好的解决方案,但它可能会有所帮助。