Использование памяти фонового изображения Android
В проекте, над которым я работаю, используется несколько "высоких разрешений" (обратите внимание на кавычки). Чтобы попасть в ситуацию, один из них представляет собой PNG файл размером 640x935 1.19M. Насколько я знаю, даже если Android распакует изображения в память в качестве исходных данных, это должно быть:
640 x 935 x 4bytes = 2.39M
У меня возникают проблемы с памятью в моем проекте, которые я не могу понять, и надеюсь, что кто-то может пролить свет на этот вопрос. Я назову два устройства, которые я разрабатываю, и некоторые результаты.
Чтобы убедиться, что это не была вторичная проблема, я сделал операцию, не загружая фон при первом создании, а затем, когда пользователь нажимает кнопку, все, что она делает, это:
findViewById(R.id.completed_block_background).setBackgroundResource(R.drawable.blockbackgroundbottom1);
Затем, используя DDMS с "Update Heap" в процессе (и сначала заставляя GC удостовериться, что это не будет проблемой), я получаю следующие результаты памяти:
Nexus S: переход от 18M к 26M (разность 8M)
Galaxy Nexus: переход от 28M к 39M (разница 11M)
Итак, как вы можете видеть, теоретически размещение несжатого изображения 2.39M в фоновом режиме фактически увеличивает использование памяти 8M и 11M. Может кто-нибудь объяснить, почему это так и если есть какое-то решение?
Единственным решением, которое я смог найти, является использование растровых изображений для уменьшения разрешения или уменьшения формата канала (до сих пор это то, что я сделал, переключил их на 565 RGB, но это создает некоторые проблемы с диапазоном, которые я не могу принять).
Я бы тоже согласился, если ничего не может быть сделано, объяснение того, почему это происходит. Спасибо заранее.
Ответы
Ответ 1
Вот почему это делает изображение таким большим?
Что происходит, так это то, что setBackgroundResource(R.drawable.blockbackgroundbottom1)
заставит Android сначала выполнить BitmapFactory.decodeResource()
вещь, с которой вы экспериментировали, но затем визуализируйте визуализацию, чтобы применить ее как фон. Так, например, разница 3 МБ между Galaxy Nexus и Nexus S, вероятно, отражает разницу в размерах в пикселях между версиями LinearLayout
.
Также может произойти передискретизация на основе плотности экрана, в зависимости от того, где вы сохранили это изображение в дереве ресурсов.
Можно ли каким-либо образом сохранить исходный размер изображения?
Сбросьте манжету, я сначала попробую положить ее в res/drawable-nodpi/
(чтобы предотвратить любую автоматическую передискретизацию на основе плотности), а затем вручную получить Bitmap
через версию BitmapFactory.decodeResource()
, которая принимает BitmapFactory.Options
, поэтому вы можете получить его масштабированным, поскольку он читается. Если это, похоже, мало помогает, вам может потребоваться перенести PNG из доступных ресурсов и в сырьевой ресурс или активы, поскольку Android все еще может попытаться удерживать un- масштабированной копии изображения. Я не думаю, что это произойдет, если вы непосредственно используете BitmapFactory.decodeResource()
, но я не могу это исключить.