使用滑动加载大尺寸图像时出现OutOfMemoryException

时间:2015-06-08 20:17:13

标签: android out-of-memory android-glide

所以,我一直在使用这个了不起的库Glide在我的图库应用中显示原生图像。我正在使用ViewPagerFragmentStatePagerAdapter来显示完整尺寸的图片。寻呼机的屏幕外限为1(默认为保存内存)。我正在使用此代码将图像加载到我的片段中的ViewPager

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

现在,我在这里面临一些问题:

  1. 图片需要相当长的时间才能加载(如果没有缓存)。因此,当用户滚动浏览器时,在加载图像时会显示空白屏幕,这是我想要避免的。有什么方法可以做到这一点吗?也许通过预先存储图像?
  2. 有时,在滚动浏览大尺寸图像(主要是相机照片)时,会抛出 OOM异常,并且由于没有加载图像,用户会留下空白屏幕。当我从potrait转为横向模式时,也会发生这种情况。因此,我尝试使用像atMost()这样的方法 - 这会降低图像的质量,因为图像已经加载到RGB_565approximate()中,这也会导致OOM。如何在不获得OOM异常的情况下实现最高图像质量?
  3. 对于第二个问题,我正在考虑为屏幕外项目加载质量较差的图像,然后在屏幕上显示时提高质量。有可能吗?

    我也试过使用ARGB_8888但结果是一样的:OOM例外。

1 个答案:

答案 0 :(得分:22)

TL; DR

  • 确保ImageView具有match_parent或固定dp作为尺寸
    wrap_content使Glide加载全分辨率位图。
  • .placeholder()在加载大型位图时显示图像而不是空白
  • .thumbnail(float)快速加载缩减采样版本,而较大图像在后台加载
  • 还要看看the Glide issues,也许你会发现一些有用的东西。

详细信息

我很好奇xml对于ImageView是什么,因为我的猜测是wrap_content导致将图像以全分辨率加载到Bitmap s(使用很多记忆)。如果是这种情况,我建议您使用match_parent或修复dp来降低分辨率。注意:您不会使用细节,因为目前无论如何都会在渲染时对图像进行下采样,只需将其向前推进到解码阶段。

您还必须确保您的应用没有内存使用限制。你可以在没有Glide的情况下将3张(off screen limit = 1 means 1+current+1 pages)相机照片加载到位图中吗?同样,假设这是全分辨率,应该可以在有或没有Glide的情况下在内存中存储3个屏幕大小的字节数量,但是你必须引导Glide不以全分辨率加载。

您可以通过.thumbnail()加载较小尺寸的图片,它会接受full Glide.with... not including .into()或其中只有一个百分比(0.0 ... 1.0),shorthand parameter,尝试后者首先。它应该更快地对图像进行解码,特别是对于像0.1这样的非常小的数字,然后当更高质量的图像完成它被替换时。

因此,更简单的选择是将.thumbnail()添加到当前负载。一个更复杂的问题涉及在创建Fragment视图的同时开始使用.sizeMultiplier()加载较低分辨率的图像,然后在{{1}时开始加载高分辨率图像已更改页面。这有助于窥视页面。

或者你可以在图片加载时使用.placeholder(),这样它就不是空白空间,而是"某些东西"那里。

关于使用ViewPager(每像素32位):如果增加ARGB_8888消耗的内存(与Bitmap相比(每像素16位),不要期望以后让你的内存耗尽。一旦你使用565你可以尝试增加,但在那之前它是徒劳的尝试。

同时浏览the Glide issues,也许你会找到有用的东西。

相关问题