2015-10-01 5 views
-2

Я реализовал ViewPager, который будет содержать 5 битмапов. Мои изображения не более 50 кб каждая. Когда инициализируется ViewPager, создается первое 2 изображения, но память, которую они потребляют, составляет 100 МБ! После второго изображения мое приложение потребляет около 256 МБ памяти, что на 190 Мбайт больше, чем обычное использование памяти. Это происходит только после создания 3 изображений. (Всего 150 КБ)Работа с растровыми изображениями - OutOfMemoryError

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

Вход

Initialize start 
﹕ Position 0 is created 
﹕ Position 1 is created 
Initialize end 
Swipe Next image (1) 
﹕ Position 2 is created 
Swipe Next image (2) 
﹕ Position 0 is destroyed 
﹕ Position 3 is created 
Swipe Next image (3) 
﹕ Position 1 is destroyed 
﹕ Position 4 is created 
Swipe Next image (4)(last image) 
﹕ Position 2 is destroyed 
Swipe Previous image (3) 
﹕ Position 2 is created 
Swipe Previous image (2) 
CRASHED 

Вот мой адаптер

class CustomPagerAdapter extends PagerAdapter { 

    Context mContext; 
    LayoutInflater mLayoutInflater; 

    public CustomPagerAdapter(Context context) { 
     mContext = context; 
     mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    @Override 
    public int getCount() { 
     return NUM_PAGES; 
    } 

    @Override 
    public boolean isViewFromObject(View view, Object object) { 
     return view == ((LinearLayout) object); 
    } 

    @Override 
    public Object instantiateItem(ViewGroup collection, int position) { 
     DebugLog.debug(TAG,"Position " + position + " is created"); 
     View itemView = mLayoutInflater.inflate(R.layout.pager_item, collection, false); 
     ImageView imageView = (ImageView) itemView.findViewById(R.id.imageView); 
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), mResources[position]); 
     imageView.setImageBitmap(bitmap); 
     collection.addView(itemView); 
     return itemView; 
    } 

    @Override 
    public void destroyItem(ViewGroup container, int position, Object object) { 
     View view = (View)object; 
     ImageView imageView = (ImageView) view.findViewById(R.id.imageView); 
     BitmapDrawable bmpDrawable = (BitmapDrawable) imageView.getDrawable(); 
     if (bmpDrawable != null && bmpDrawable.getBitmap() != null) { 
      bmpDrawable.getBitmap().recycle(); 
      DebugLog.debug(TAG, "Position " + position + " is destroyed"); 
     } 
     container.removeView((LinearLayout) object); 
     view = null; 
    } 
} 
+3

Растровый держит несжатое изображение и требует 3 или 4 (с альфа) байт на пиксель. Таким образом, даже если ваш образ (jpg, png, ...) мал, он все равно может быть огромным, когда несжатый. – Ridcully

+0

32 бит * x px * y px, по крайней мере. –

+0

Я сконфигурировал sampleSize до 2 перед декодированием и, похоже, потребляет меньше памяти. – Alpaslan

ответ

0

Добавить в адаптере частные Hashmap usedImages;

... 
public CustomPagerAdapter(Context context) { 
    ... 
    usedImages=new HashMap<>(); 
    } 

    @Override 
public Object instantiateItem(ViewGroup collection, int position) { 
    DebugLog.debug(TAG,"Position " + position + " is created"); 
    View itemView = mLayoutInflater.inflate(R.layout.pager_item, collection, false); 
    ImageView imageView = (ImageView) itemView.findViewById(R.id.imageView); 
       Bitmap bitmap = BitmapFactory.decodeResource(getResources(), mResources[position]); 
    imageView.setImageBitmap(bitmap); 
    usedImages.put(position, bitmap);   
    collection.addView(itemView); 
    return itemView; 
} 


@Override 
public void destroyItem(ViewGroup container, int position, Object object) { 
    View view = (View)object; 
    ImageView imageView = (ImageView) view.findViewById(R.id.imageView); 
    imageView.setImageBitmap(null); 
    Bitmap bitmap = usedImages.get(position); 
    if (bitmap != null) { 
     bitmap.recycle(); 
     bitmap = null; 
    } 

    usedImages.remove(position); 
    container.removeView(view); 
} 

метод добавление ясно() к адаптеру и вызвать его в OnDestroy активности или фрагмента:

public void clear(){ 
    if(usedImages!=null) { 
     for (Map.Entry<Integer, Bitmap> item : usedImages.entrySet()) { 
      Bitmap bitmap = item.getValue(); 
      if (bitmap != null) { 
       bitmap.recycle(); 
       bitmap = null; 
      } 
     } 
     usedImages.clear(); 
     usedImages = null; 
    } 
    mContext = null; 
    mLayoutInflater=null; 

} 
+0

Я применил ваш метод для утилизации использованных изображений, но он по-прежнему не освобождает память, используемую изображениями – Alpaslan

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