OutOfMemoryException при загрузке изображений большого размера с использованием скольжения

Итак, я использовал эту замечательную библиотеку Glide для показа собственных изображений в моем приложении галереи. Я использую ViewPager с FragmentStatePagerAdapter для отображения полноразмерных изображений. Предел выключения экрана пейджера составляет 1 (по умолчанию для экономии памяти). Я использую этот код для загрузки изображений в ViewPager своего фрагмента:

Glide.with(getActivity())
     .loadFromMediaStore(uri)
     .asBitmap()
     .signature(new MediaStoreSignature(mimeType, dateModified, 
     .into(mImageView);

Теперь я столкнулся с некоторыми проблемами, например:

  1. Загрузка изображений занимает некоторое время (если они не кешированы). Итак, пока пользователь прокручивает окно просмотра, отображается пустой экран во время загрузки изображения, чего я хочу избежать. Как я могу это сделать? Может быть, путем предварительного кеширования изображений?
  2. Иногда при прокрутке изображений большого размера (в основном фотографий с камеры) возникает исключение OOM, и пользователь остается с пустым экраном, поскольку изображение не загружено. Это также происходит, когда я переключаюсь из портретного режима в альбомный. Итак, я попытался использовать такие методы, как atMost(), которые дополнительно ухудшают качество изображения, поскольку изображения уже загружены в RGB_565 и approximate(), что также вызывает OOM. Как добиться максимального качества изображения без исключений OOM?

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

Я также пробовал использовать ARGB_8888, но результат был таким же: исключение OOM.


person harry perry    schedule 08.06.2015    source источник


Ответы (1)


TL;DR

  • Убедитесь, что ImageView имеет match_parent или фиксированный dp в качестве размеров
    wrap_content заставляет Glide загружать растровые изображения с полным разрешением.
  • .placeholder() показывает изображение вместо пустого места при загрузке большого растрового изображения
  • .thumbnail(float) быстро загружает версию с пониженной дискретизацией, в то время как более крупное изображение загружается в фоновом режиме
  • Также посмотрите проблемы с Glide , может быть, ты найдешь что-нибудь полезное.

Подробности

Мне было бы любопытно, что это за xml для ImageView, потому что я предполагаю, что это wrap_content, что приводит к загрузке изображений с полным разрешением в Bitmaps (с использованием большого количества памяти). В таком случае я бы предложил использовать match_parent или фиксированный dp, чтобы снизить разрешение. Примечание: вы не будете использовать детализацию, потому что в настоящее время изображение в любом случае подвергается субдискретизации во время рендеринга, просто перетаскивая его на этап декодирования.

Вы также должны убедиться, что ваше приложение не имеет ограничений на использование памяти. Можете ли вы загрузить 3 (off screen limit = 1) означает 1+current+1 страниц) фото с камеры в растровые изображения без скольжения? Опять же, предполагая, что это полное разрешение, должно быть возможно сохранить в памяти количество байтов размером 3 экрана с Glide или без него, но вы должны указать Glide, чтобы он не загружался в полном разрешении.

Вы можете загрузить изображение меньшего размера через .thumbnail(), оно принимает полный Glide.with..., не включая .into() ИЛИ есть сокращенный параметр, который представляет собой просто процент (в 0.0 ... 1.0), сначала попробуйте последний. Он должен декодировать изображение намного быстрее, особенно с действительно маленьким числом, например 0,1, а затем, когда более качественное изображение заканчивается, оно заменяется.

Так что более простой вариант - добавить .thumbnail() к вашей текущей нагрузке. Более запутанный вариант предполагает загрузку изображения с более низким разрешением с _ 18_ одновременно с созданием Fragment представления и началом загрузки представления с высоким разрешением, когда ViewPager изменилась страница. Это помогает просматривать страницы.

В качестве альтернативы вы можете просто использовать .placeholder() < / a> пока изображение загружается, так что это не пустое место, а что-то там.

Что касается использования ARGB_8888 (32 бит на пиксель): если вы увеличите объем памяти, потребляемой на Bitmaps (по сравнению с RGB_565 (16 бит на пиксель), не ожидайте, что память закончится позже. Как только вы получите его работу с 565, вы можете попробовать увеличивается, но до тех пор бесполезно пытаться.

Также посмотрите проблемы с Glide , может быть, ты найдешь что-нибудь полезное.

person TWiStErRob    schedule 25.06.2015