Страницы

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

суббота, 6 июля 2019 г.

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

Уже не раз сталкивался с проблемой утечек памяти, когда вылетает 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; при декодировании битмапа действительно помогла. Все равно остается много вопросов.


Ответ

Смотрите в сторону 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() - там можно попробовать кое-что неиспользуемое выгрузить/закрыть и проч.

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

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