Использование памяти фонового изображения 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(), но я не могу это исключить.