Когда безопасно/возможно повторно использовать растровое изображение в Android SimpleCursorAdapter с представлением галереи?

При отображении галереи с большим количеством больших растровых изображений (полноэкранный режим, wvga) у меня довольно часто возникают проблемы с памятью. Я предполагаю, что это связано с тем, что растровые изображения не перерабатываются. Когда/как я могу заставить растровые изображения быть переработанными?

Я также заметил, что в методе getView для simpleCursorAdapter convertView всегда имеет значение null. Я предполагаю, что это означает, что старый вид не переработан? Даже при прокрутке вперед и назад каждый раз создается новый вид. Однако прокрутка вперед и назад не вызывает проблем с нехваткой памяти, это происходит только тогда, когда общее количество изображений достаточно велико.

При использовании того же адаптера с ListView представления перерабатываются, поэтому проблема, похоже, связана с галереей.

Что я могу сделать, чтобы принудительно перезапустить виды и/или растровые изображения? Что еще я могу сделать, чтобы управлять памятью, не уменьшая размер галереи и качество растрового изображения.


person Gunnar Lium    schedule 15.12.2010    source источник
comment
Пробовали ли вы различные варианты растровых изображений, такие как purgeable — используете ли вы предварительно масштабированные или высококачественные изображения для галереи? Вы видели SoftReference/WeakReference для управления памятью?   -  person Sebastian Roth    schedule 15.12.2010


Ответы (2)


Вы можете использовать recycle(), если уверены, что больше не будете использовать растровое изображение, например, в какой-либо операции с временным растровым изображением. Но... Вы можете использовать BitmapFactory.Options, например:

BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inPurgeable=true;

Bitmap bitmapTemp = BitmapFactory.decodeResource(getResources(), R.drawable.intro, bitmapOptions);

Что оно делает? опция inPurgeable будет предполагать, что, как только системе понадобится память, а ваше растровое изображение станет бесполезным, система сама переработает это выделение памяти. Если по какой-то причине вы не можете загрузить изображение с помощью BitmapFactory, вы можете использовать Recycle(), и рекомендуется вызывать сборщик мусора, а затем с помощью system.gc(), это полезно, если вы разрабатываете, например, игру, потому что когда сборщик мусора, который активируется, когда в вашей системе мало памяти, он будет потреблять несколько ценных миллисекунд. Вы должны быть очень осторожны с растровыми изображениями, они не хранятся в «обычной» памяти, используемой вашим приложением, они хранятся в «общей» памяти, используемой всеми вашими приложениями, если вы не используете Android 3.0. Если у вас есть утечка памяти и вы не можете найти ее, глядя на кучу... вам следует взглянуть на загрузку кода и использование растровых изображений. Надеюсь, поможет.

person Kofa    schedule 19.01.2012

Вам никогда не нужно перерабатывать Bitmap. Однако вы можете сделать это, и это поможет, если у вас есть OutOfMemory ошибок. Но не делайте этого до тех пор, пока растровое изображение больше не понадобится, потому что (из javadoc)

он выдаст исключение, если будет вызван getPixels() или setPixels(), и ничего не отрисует. Эту операцию нельзя отменить, поэтому ее следует вызывать только в том случае, если вы уверены, что растровое изображение больше не используется.

В вашем случае я предполагаю, что вы должны:

  • используйте превью, растровое изображение, открытое с помощью BitmapFactory.Options.inSampleSize или MediaStore.Images.Thumbnails
  • Имейте в памяти не более одного полноразмерного растрового изображения (возможно, одно предварительно загруженное, которое вы можете себе позволить)
person rds    schedule 15.12.2010
comment
верно, вам необходимо это делать, но ваше приложение рухнет, если вы этого не сделаете. как именно вы определяете потребность? - person Jeffrey Blattman; 23.04.2011
comment
Google определяет потребность по-другому. Вы должны перерабатывать растровые изображения в pre-HC. - person Raz; 14.03.2012