размер растрового изображения превышает бюджет виртуальной машины Ошибка на Android - PullRequest
3 голосов
/ 18 августа 2011

Я загружаю 100 изображений из папки активов в объект массива. Картинки довольно маленькие (png ~ 20k каждая), и я использую этот код, чтобы предотвратить утечку памяти и оптимизировать производительность:

в цикле:

// create resized bitmap from asset resource
        InputStream istr = assetManager.open(pics[i]);
        Bitmap b = BitmapFactory.decodeStream(istr);
        b = Bitmap.createScaledBitmap(b, 240, 240, true);

где pics [i] - список имен файлов, который находится в моей папке активов.

Код работает для меня, но я все еще время от времени получаю ошибки от пользователей (я вижу это на ошибках консоли разработчика):

java.lang.OutOfMemoryError: bitmap size exceeds VM budget
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:468)
at android.graphics.Bitmap.createBitmap(Bitmap.java:435)
at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:340)

Что я могу сделать, чтобы улучшить это? или это мир Android, мы никогда не сможем создать идеальное приложение?

Ответы [ 3 ]

2 голосов
/ 18 августа 2011

Конечно, вы можете что-то улучшить: не загружайте в память слишком много картинок одновременно (и не уменьшайте их размер). Некоторые устройства не имеют много доступной памяти. Ваше устройство может иметь более высокий предел кучи, чем некоторые из ваших телефонов клиентов. Поэтому он падает для них, когда работает для вас (см. это видео для некоторых ограничений кучи [в 4:44]).

Доступный размер кучи вы можете получить через ActivityManager.getMemoryClass().

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

Также попробуйте использовать BitmapFactory.decodeResource() и BitmapFactory.Options.inSampleSize. Это позволяет загружать изображения с более низким разрешением напрямую, не загружая их в полном размере, а затем изменяя их размер, как вы сделали здесь.

2 голосов
/ 18 августа 2011

Растровые изображения не сжимаются, поэтому они хранятся в width * height * 4 байтах. Это означает, что каждое изображение использует около 225 КБ памяти. 100 изображений требуют около 22 МБ памяти. Минимальный размер кучи составляет 16 МБ, но устройства обычно имеют кучи более 24 МБ. И эта куча используется не только для данных, но и для действий, просмотра и так далее. Это означает, что вы не можете загрузить 100 битмапов такого размера.

1 голос
/ 18 августа 2011

Как правило, нужно только , чтобы показать, что пользователь действительно может видеть.Хранение чего-либо еще (графика) в памяти - просто глазурь на торте.Вот почему устройства с экранами с более высоким разрешением будут иметь большие размеры кучи.

Например, на экране с разрешением 320x480 требуется всего 320x480x4 = 614400 (600 КБ).Принимая во внимание эту концепцию, вы должны решить, нужно ли вам , чтобы хранить 100 Bitmap с в памяти.Пользователь смотрит на 100 Bitmap с одновременно?В этом случае вы можете снизить качество изображений, не ухудшая пользовательский интерфейс (на экране всего столько пикселей).Пользователь прокручивает 100 Bitmap с?Затем создайте динамический дамп и загрузите изображения соответствующим образом (с небольшим кэшированием для плавности).

Обходной путь всегда есть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...