Android ListActivity с растровыми изображениями и сборкой мусора - PullRequest
0 голосов
/ 01 апреля 2012

У меня есть ListActivity, и в нем я установил элементы списка с классом, который расширяет SimpleCursorAdapter.Я переопределяю bindView, чтобы установить Views.У меня есть TextViews и ImageViews.Вот как я устанавливаю элементы списка в моем адаптере курсора:

String variableName = "drawable/q" + num + "_200px";
int imageResource = context.getResources().getIdentifier(variableName, "drawable", context.getPackageName());
if (imageResource != 0 ) {
    // The drawable exists
    Bitmap b = BitmapFactory.decodeResource(context.getResources(), imageResource);
    width = b.getWidth();
    height = b.getHeight();
    imageView.getLayoutParams().width = (int) (width);
    imageView.getLayoutParams().height = (int) (height);
    imageView.setImageResource(imageResource);
} else {
    imageView.setImageResource(R.drawable.25trans_200px);
}

Проблема, с которой я сталкиваюсь, заключается в том, что всякий раз, когда я обновляю свой список с помощью setListAdapter, я получаю большое количество мусора:

D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 125K, 51% free 2710K/5447K, external 2022K/2137K, paused 75ms
D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 30K, 51% free 2701K/5447K, external 2669K/2972K, paused 64ms
D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 23K, 51% free 2713K/5447K, external 3479K/3579K, paused 53ms
D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 22K, 51% free 2706K/5447K, external 3303K/3352K, paused 64ms
D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 21K, 51% free 2722K/5447K, external 3569K/3685K, paused 102ms
D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 23K, 50% free 2755K/5447K, external 3499K/3605K, paused 65ms
D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 23K, 50% free 2771K/5447K, external 4213K/4488K, paused 53ms
D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 18K, 49% free 2796K/5447K, external 5057K/5343K, paused 75ms
D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 28K, 49% free 2803K/5447K, external 5944K/5976K, paused 53ms
D/dalvikvm(  435): GC_EXPLICIT freed 6K, 54% free 2544K/5511K, external 1625K/2137K, paused 50ms
D/dalvikvm(  165): GC_EXPLICIT freed 85K, 52% free 2946K/6087K, external 4838K/5980K, paused 111ms
D/dalvikvm(  448): GC_EXPLICIT freed 1K, 54% free 2540K/5511K, external 1625K/2137K, paused 50ms
D/dalvikvm(  294): GC_EXPLICIT freed 8K, 55% free 2598K/5703K, external 1625K/2137K, paused 64ms

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

1 Ответ

1 голос
/ 01 апреля 2012
  1. Вам не нужно загружать растровое изображение только для того, чтобы получить длину и ширину. Вероятно, вы захотите взглянуть на свойство ImageView scaleType . Это отрегулирует границы ImageView в соответствии с загружаемым изображением.
  2. Ваш код подразумевает, что у вас есть несколько состояний изображения на основе числа. Возможно, вы захотите взглянуть на LevelListDrawable XML для этого. В основном вы можете установить список доступных для рисования элементов по номеру, который вы им передали. Если вы присваиваете LevelListDrawable для ImageView в XML или в коде. Все, что вам, вероятно, придется сделать, это вызвать imageView.setImageLevel (num) .

bindView является критическим методом при анимации списка. Он вызывается при прокрутке ListView и загрузке новых элементов, потому что они появляются. bindView вызывается в потоке пользовательского интерфейса, что означает, что анимация не может продолжаться, пока не завершится. Обычно это не проблема, потому что вы просто присваиваете переменные. В этом коде вы звоните Bitmap b = BitmapFactory.decodeResource(context.getResources(), imageResource);, который должен поразить флеш-память NAND, которая стоит дорого. Вы можете использовать StrictMode для обнаружения подобных проблем.

Растровые изображения выгружаются из памяти, когда они больше не используются, но это не сразу, GC должен вызываться. Android предлагает способ отбрасывать данные большого байтового массива, переносимые растровыми изображениями, с помощью метода Bitmap.recycle () . Это, мы надеемся, решит OutOfMemoryError's.

Если описанные выше подходы по какой-то причине не работают, вам придется иметь дело с более сложным решением, которое включает потоки и обратные вызовы.

Дайте мне знать, если вам нужна помощь с этим. Не могли бы вы уточнить, зачем вам ширина и высота изображения?

...