我构建了一个自定义视图(类似于网格视图),它显示了许多许多图像,因此回收位图是此应用程序的必要条件。我正在使用 Lru 缓存(在下面实现)来处理位图回收。当我在 Android 2.3 设备上测试这个(并快速滚动)时,我收到以下错误消息并且应用程序崩溃了。在弄清楚如何复制该错误后,我在 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 之前检查了位图是否被回收。但是,位图在该步骤和 draw() 步骤之间被回收,从而导致错误。
这是我的缓存:
sLruCache = new LinkedHashMap(容量 / 2, 0.75f, true) {
私有静态最终长序列版本UID = -7282875042976381535L;
@覆盖
protected boolean removeEldestEntry(LinkedHashMap.Entry eldest) {
如果(大小()> mCapacity){
返回真;
} 别的
返回假;
}
公共位图删除(对象键){
位图 bitmap = super.remove(key);
如果(位图!= NULL_BITMAP){
bitmap.recycle();
}
返回位图;
};
@覆盖
公共无效清除(){
设置键 = new HashSet(keySet());
对于(字符串键:键){
位图映射 = get(key);
如果(地图!= NULL_BITMAP){
map.recycle();
}
}
超级清除();
}
};
关于为什么这会在 Android 2.3 而不是 4.0 上失败的任何想法?