我正在使用一个LRUCache
缓存存储在文件系统上的位图。我根据这里的示例构建了缓存:http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
问题是我在使用该应用程序时经常看到内存不足崩溃。我相信,当 LRU 缓存驱逐一个图像以为另一个图像腾出空间时,内存并没有被释放。
当图像被逐出时,我添加了对 Bitmap.recycle() 的调用:
// use 1/8 of the available memory for this memory cache
final int cacheSize = 1024 * 1024 * memClass / 8;
mImageCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getByteCount();
}
@Override
protected void entryRemoved(boolean evicted, String key, Bitmap oldBitmap, Bitmap newBitmap) {
oldBitmap.recycle();
oldBitmap = null;
}
};
这修复了崩溃,但也会导致图像有时没有出现在应用程序中(只是图像应该出现的黑色空间)。每当发生这种情况时,我都会在 Logcat 中看到此消息:Cannot generate texture from bitmap
.
快速谷歌搜索显示,发生这种情况是因为显示的图像已被回收。
那么这里发生了什么?如果我只是在删除图像后才回收它们,为什么回收的图像仍保留在 LRUCache 中?
实现缓存的替代方案是什么? Android 文档明确指出 LRUCache 是可行的方法,但他们没有提到回收位图的需要或如何做到这一点。
解决:如果它对其他人有用,则按照接受的答案建议的解决方案是NOT执行我在上面的代码示例中所做的操作(不要回收entryRemoved()
call).
相反,当您完成 ImageView 后(例如onPause()
在活动中,或者在适配器中回收视图时)检查位图是否仍在缓存中(我添加了一个isImageInCache()
方法到我的缓存类),如果不是,则回收位图。否则,别管它。这修复了我的OutOfMemory
异常并阻止回收仍在使用的位图。