Страницы

Поиск по вопросам

среда, 22 января 2020 г.

Корректная работа с памятью в Android

#getview #android #java


Уже не раз сталкивался с проблемой утечек памяти, когда вылетает java.lang.OutOfMemoryError
и в частности java.lang.OutOfMemoryError: Bitmap Size Exceeds VM Budget.

Сейчас делаю листалку в галереи и столкнулся с этой ошибкой. С первым вариантом.
Версия дроида 4.0.3(не до конца обновленный galaxy s2).

Сразу нагуглилось это  Сделал пару советов оттуда - результат такой же.
Посему вопрос для тех кто сталкивался и решал проблемы: как с этим боритесь вы?

Что само интересное - ошибка вылетает на листании миниатюр, а на листании больших
картинок все гуд!

UPD 1
Убираю атрибут adjustViewBounds в ImageView элемента галереи и все листается без ошибок.

UPD 2
Код:

public View getView(int position, View convertView, ViewGroup parent) {
    ThumbViewHolder holder;

    View view = convertView;
    if( convertView == null ){
        convertView = LayoutInflater.from(mContext).inflate(resId, null);
        holder = new ThumbViewHolder();
        ImageView img = (ImageView)convertView.findViewById(R.id.image);

        holder.img = img;
        convertView.setTag(holder);
    }
    else {
         holder = (ThumbViewHolder)convertView.getTag();
    }

    //BitmapFactory.Options opts = new BitmapFactory.Options();
    //opts.outWidth = 10;
    //opts.outHeight = 10;
    Bitmap bmp = BitmapFactory.decodeFile(images.get(position));
    holder.img.setImageBitmap(bmp);

    return convertView;
  }


без использования холдера тоже самое.

UPD 3
Нужно также отметить что картинки имею разрешение 992х1370. И таких картинок много.

UPD 4
Опция opts.inSampleSize = 2; при декодировании битмапа действительно помогла.
Все равно остается много вопросов.
    


Ответы

Ответ 1



Смотрите в сторону BitmapFactory.Options.inPurgeable=true в этом случае при нехватке памяти битмап будет выгружаться на диск. Мне это помогло. P.S. Опция работает только начиная с API 4 Update Есть еще другая полезная фича: BitmapFactory.Options.inSampleSize=2 - вдвое уменьшает размер битмапов: If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory. The sample size is the number of pixels in either dimension that correspond to a single pixel in the decoded bitmap. For example, inSampleSize == 4 returns an image that is 1/4 the width/height of the original, and 1/16 the number of pixels. Any value <= 1 is treated the same as 1. Note: the decoder will try to fulfill this request, but the resulting bitmap may have different dimensions that precisely what has been requested. Also, powers of 2 are often faster/easier for the decoder to honor. Кроме этого рекомендую посмотреть в сторону метода: Application.onLowMemory() - там можно попробовать кое-что неиспользуемое выгрузить/закрыть и проч.

Ответ 2



Я может чегото недопонял. Вы в список грузите большие картинки, просто масштабируя их под нужный размер? Если да, то: нужно использовать inSampleSize подробно здесь: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html Ну и рециклинг обязательно. Будет работать медленнее зато эффективнее с памятью

Комментариев нет:

Отправить комментарий