Когда следует перерабатывать растровое изображение с помощью LRUCache?

Я использую 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(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: Невозможно сгенерировать текстуру из растрового изображения .

Быстрый поиск в Google показывает, что это происходит потому, что отображаемое изображение было переработано.

Так что же здесь происходит? Почему переработанные изображения все еще находятся в LRUCache, если я перерабатываю их только после того, как они были удалены? Какова альтернатива реализации кеша? В документации по Android четко указано, что LRUCache — это то, что нужно, но в них не упоминается необходимость перерабатывать растровые изображения или как это сделать.

РЕШЕНО: В случае, если это полезно для кого-либо еще, решение этой проблемы, предложенное принятым ответом, состоит в том, чтобы НЕ делать то, что я сделал в приведенном выше примере кода (не перерабатывать растровые изображения в entryRemoved ()вызов).

Вместо этого, когда вы закончите работу с ImageView (например, onPause()в действии или когда представление повторно используется в адаптере), проверьте, находится ли растровое изображение в кеше (I добавил метод isImageInCache()к моему классу кеша) и, если это не так, то переработать растровое изображение. В противном случае оставьте его в покое.Это исправило мои исключения OutOfMemoryи предотвратило повторное использование растровых изображений, которые все еще использовались.

54
задан howettl 25 May 2012 в 05:27
поделиться