Android – Кэш Bitmap занимает много памяти

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

Весь код Chath Bitmap в значительной степени скопирован отсюда: http://developer.android.com/training/displaying-bitmaps/index.html

Я отлаживал код и проверял размер кучи в представлении DDMS в eclipse, и после этих строк кода происходит скачок в 15 мб:

options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options); 

в методе «decodeSampledBitmapFromResource».

Изображение – 1024×800, 75kb jpg-файл. Согласно тому, что я уже видел в Интернете, объем памяти, который предполагается использовать этому изображению, составляет около 1024 * 800 * 4 (байт на пиксель) = 3,125 МБ

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

РЕДАКТИРОВАТЬ

Я попытался использовать метод decodeFile, предложенный в ответе @ ArshadParwez ниже. Используя этот метод, после метода BitmapFactory.decodeStream память увеличивается только на 3,5 Мб – проблема решена, но я хочу кэшировать растровые изображения непосредственно из ресурса.

Я заметил, что во время метода decodeResource есть 2 памяти «прыжки» – один из около 3,5 Мб, что разумно, а еще один странный один из 14mb. Для чего используются 14mb и почему это происходит?

Изображения также масштабируются в соответствии с плотностью, поэтому они могут использовать много памяти.

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

Таким образом, в вашем примере байты, которые будет использоваться файлом изображения, следующие:

(1024 * 2) * (800 * 2) * 4 = 13,107,200 байт.

Было бы еще хуже, если бы вы запустили его на устройстве xxhdpi (например, HTC one и Galaxy S4).

Что ты можешь сделать? Поместите файл изображения в нужную папку плотности ( drawable-xhdpi или drawable-xhdpi drawable-xxhdpi ) или поместите его в drawable-nodpi (или в папку с ресурсами) и уменьшите изображение в соответствии с вашими потребностями.

BTW вам не нужно устанавливать options.inJustDecodeBounds = false поскольку это поведение по умолчанию. Фактически вы можете установить значение null для параметров растрового изображения.

О масштабировании вниз вы можете использовать либо путь Google, либо мой способ, каждый из которых имеет свои преимущества и недостатки.

О кешировании есть много способов сделать это. Наиболее распространенным является кеш LRU. Существует также альтернатива, которую я создал недавно (ссылка здесь или здесь ), которая позволяет вам кэшировать намного больше изображений и избегать использования OOM, но это дает вам большую ответственность.

Вы можете использовать этот метод для передачи изображения и получения растрового изображения:

 public Bitmap decodeFile(File f) { Bitmap b = null; try { // Decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; FileInputStream fis = new FileInputStream(f); BitmapFactory.decodeStream(fis, null, o); fis.close(); int IMAGE_MAX_SIZE = 1000; int scale = 1; if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) { scale = (int) Math.pow( 2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5))); } // Decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; fis = new FileInputStream(f); b = BitmapFactory.decodeStream(fis, null, o2); fis.close(); } catch (IOException e) { e.printStackTrace(); } return b; } 

@Ori Wasserman: В соответствии с вашим запросом я использовал метод для получения изображений из папки ресурсов, и я тоже использовал изображение 7 МБ. Я помещал изображение 7 МБ в папку «res-> drawable» и со следующим кодом он не разбился и изображение было показано в представлении изображения:

  Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.image_7mb); loBitmap = Bitmap.createScaledBitmap(image, width_of_screen , height_of_screen, true); imageview.setImageBitmap(loBitmap); 
  • Как проверить, не является ли текущий stream не основным streamом
  • Как проверить, работает ли приложение на Android?
  • Обнаружение изменений состояния, внесенных в BluetoothAdapter?
  • Строка Android Split
  • Как программно установить drawableLeft на кнопку Android?
  • ISO 8601 Объект String to Date / Time в Android
  • Как добавить каталог в путь к classам в профиле запуска приложения в IntelliJ IDEA?
  • Как преобразовать данные Firebase в объект Java ...?
  • Android Row становится Unclickable с кнопкой
  • math.random, только генерируя 0?
  • ksoap2 org.xmlpull.v1.xmlpullparserexception Ожидаемая ошибка start_tag
  • Давайте будем гением компьютера.