2015-04-19 4 views
1

У меня проблема.Загрузка Android в ImageView занимает много памяти

Я загружаю 9 drawables в 9 imageViews динамически. (drawables различаются каждый раз) Идентификатор drawable сохраняется в классе объектов, поэтому, когда я загружаю этот drawable, я устанавливаю ImageRessource в imageView с помощью imageView.setImageRessource(myObject.getRessourceId()); Все работает нормально, но когда загружаются 9 чертежей, я вижу на Android монитор памяти, что выделение памяти достигает 80 МБ, и я думаю, что это не нормально ... (Так ли это?)

Я пробовал разные вещи, чтобы решить его:

  • Загрузите вытяжку с библиотекой Пикассо.
  • Используйте BitmapFactory.decodeResssource, чтобы создать растровое изображение, а затем setImageBitmap на изображенииView.

Со всеми методами, которые я пробовал, требуется 80 МБ выделенной памяти.

Я попытался использовать другое разрешение изображения, поэтому в ldpi (~ 30Ko/image) и в xhdpi (~ 87Ko/image), но он ничего не меняет для каждого загруженного изображения занимает около 5 МБ выделенной памяти ...

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

Спасибо заранее, я могу дать части кода, если это необходимо.

Привет

PS: ImageViews создаются динамически в методе onCreate().

+0

нагрузки масштабируемый вниз Изображения не оригинальные, можно ou поделиться кодом? –

ответ

1

Это нормальный, самый большой враг вашей памяти - это изображения. Также обратите внимание, что изображения занимают больше места в памяти, чем на диске. Это также нормально, что для загрузки требуется много времени. Решение состоит в том, чтобы загружать только большое изображение, как оно видно, и использовать кеши, чтобы быстрее загружать их в следующий раз (вам не нужно снова сбрасывать диск). Вот статья с примерным проектом с этим: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

+0

Вы правы, но чертежи загружаются 1 раз максимум, поэтому нет необходимости хранить его в кеше, я думаю .. Но спасибо за ваш ответ –

+0

Ну, вы все же можете уменьшить их до тех пор, пока не потребуется столько же msmory, сколько необходимо. Также полезно использовать кеш, чтобы не делать это каждый раз. –

+0

Благодаря вашей ссылке я уменьшаю выделенную память. Но для отображения моего изображения в приемлемом качестве он достигает около 60 МБ ОЗУ. Это правильно или слишком много? –

0

В зависимости от характера изображения на самом деле это нормально. Размер файла с современными изображениями не обязательно связан с размером, который он будет иметь в памяти, из-за используемых алгоритмов сжатия. В памяти предположительно маленький файл расширяется в фактические данные растрового изображения, что означает, что в ОЗУ будет занято больше данных, чем на SD-карте/диске.

Однако источники (а также изображения) были бы полезны для дальнейшего анализа.

Вы также можете посмотреть изображения в каком-либо телезрителе и попытаться определить, сколько ОЗУ оно занимает при загрузке в этом телезрителе. Вы можете быть удивлены размером, такие изображения занимают. Вот почему пользовательские интерфейсы с темами, которые в значительной степени зависят от изображений, настолько насыщены памятью.

+0

Да, это правда, но я, возможно, найду решение благодаря ссылке Бояна Ксенмана. Я постараюсь установить высоту и ширину растрового изображения, потому что на самом деле большой drawable загружается в маленьком imageView, так что, возможно, это решение. Я попробую это сейчас. –

+0

Да, это хороший подход. – Mjoellnir

7

Благодаря ссылке Bojan Kseneman, я уменьшаю выделенную память до 30Mb.Я использую это:

imageView.setImageBitmap(Util.decodeSampledBitmapFromResource(getResources(), id, 150, 150)); 

Util это утилита класс моего проекта

с этими методами:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, 
                 int reqWidth, int reqHeight) { 

     // First decode with inJustDecodeBounds=true to check dimensions 
     final BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inJustDecodeBounds = true; 
     BitmapFactory.decodeResource(res, resId, options); 

     // Calculate inSampleSize 
     options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 

     // Decode bitmap with inSampleSize set 
     options.inJustDecodeBounds = false; 
     return BitmapFactory.decodeResource(res, resId, options); 
    } 

И

public static int calculateInSampleSize(
      BitmapFactory.Options options, int reqWidth, int reqHeight) { 
     // Raw height and width of image 
     final int height = options.outHeight; 
     final int width = options.outWidth; 
     int inSampleSize = 1; 

     if (height > reqHeight || width > reqWidth) { 

      final int halfHeight = height/2; 
      final int halfWidth = width/2; 

      // Calculate the largest inSampleSize value that is a power of 2 and keeps both 
      // height and width larger than the requested height and width. 
      while ((halfHeight/inSampleSize) > reqHeight 
        && (halfWidth/inSampleSize) > reqWidth) { 
       inSampleSize *= 2; 
      } 
     } 

     return inSampleSize; 
    } 
+0

Это действительно работает! Спасибо за совет! – anthonymonori

+0

10 (!!!) раз уменьшено использование памяти! Спасибо! – Inoy

Смежные вопросы