Я использую LRUCache
для кэширования растровых изображений, которые хранятся в файловой системе. Я построил кеш, основанный на примерах здесь: http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
Проблема в том, что я вижу, что OutOfMemory часто сбой при использовании приложения. Я считаю, что когда LRUCache вытесняет изображение, чтобы освободить место для другого, память не освобождается.
Я добавил вызов 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
.
Быстрый поиск в Google показывает, что это происходит, потому что отображаемое изображение было переработано.
Итак, что здесь происходит? Почему вторичные изображения все еще находятся в LRUCache, если я только перерабатываю их после их удаления? Какая альтернатива для реализации кеша? В документах Android четко указано, что LRUCache - это путь, но они не упоминают о необходимости переработать растровые изображения или как это сделать.
ПОСТАНОВИЛИ:
В случае, если это полезно кому-либо еще, решение этой проблемы, предложенное принятым ответом, - НЕ делать то, что я сделал в приведенном выше примере кода (не перерабатывать растровые изображения в вызове entryRemoved()
).
Вместо этого, когда вы закончите с ImageView (например, onPause()
в действии или когда просмотр переработан в адаптере), проверьте, все ли битмап в кеше (я добавил метод isImageInCache()
к моему классу кеша), а если нет, то переработайте растровое изображение. В противном случае оставьте это в покое. Это зафиксировало мои исключения OutOfMemory
и предотвратило использование растровых изображений, которые все еще использовались.