5

所以,我一直在使用这个令人惊叹的库Glide在我的图库应用中显示原生图像。我正在使用ViewPagerwithFragmentStatePagerAdapter来显示全尺寸图像。寻呼机的屏幕外限制为1(默认为节省内存)。我正在使用此代码将图像加载到ViewPager我的片段中:

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

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

  1. 图像需要相当长的时间来加载(如果没有缓存)。因此,当用户滚动浏览器时,会在加载图像时显示空白屏幕,这是我想要避免的。有什么办法可以做到这一点吗?也许通过预先缓存图像?
  2. 有时,在滚动浏览大尺寸图像(主要是相机照片)时,会引发OOM 异常,并且由于没有加载图像,用户会出现空白屏幕。当我从纵向模式切换到横向模式时,也会发生这种情况。所以,我尝试使用类似的方法atMost()——当图像已经加载时RGB_565approximate()它会进一步降低图像的质量,这也会导致 OOM。如何在不出现 OOM 异常的情况下实现最高图像质量?

对于第二个问题,我正在考虑为屏幕外项目加载质量较低的图像,然后在它们出现在屏幕上时提高质量。可能吗?

我也尝试过使用ARGB_8888但结果是一样的:OOM异常。

4

1 回答 1

23

TL;博士

  • 确保ImageViewhasmatch_parent或 fixed dpas 尺寸
    wrap_content使 Glide 加载全分辨率位图。
  • .placeholder()加载大位图时显示图像而不是空白空间
  • .thumbnail(float)在后台加载较大的图像时快速加载下采样版本
  • 也看看Glide 问题,也许你会发现一些有用的东西。

细节

我会很好奇 xml 是什么ImageView,因为我的猜测是它wrap_content会导致以全分辨率将图像加载到Bitmaps 中(使用大量内存)。如果是这种情况,我建议使用match_parent或固定dp以降低分辨率。注意:您不会使用细节,因为目前图像在渲染时被下采样,只是将其拉到解码阶段。

您还必须确保您的应用程序没有内存使用限制。您可以在没有 Glide的情况下将 3 张(屏幕外限制 = 1 表示1+current+1页面)相机照片加载到位图中吗?同样,假设这是全分辨率,无论是否使用 Glide,都应该可以在内存中存储 3 个屏幕大小的字节数,但是您必须引导 Glide 不以全分辨率加载。

您可以通过 加载较小尺寸的图像.thumbnail(),它接受一个完整的Glide.with...不包括.into()或有一个速记参数,它只是一个百分比(在0.0 ... 1.0),请先尝试后者。它应该更快地解码图像,尤其是对于像 0.1 这样非常小的数字,然后当更高质量的数字完成时,它会被替换。

所以更简单的选择是添加.thumbnail()到您当前的负载中。一个更复杂的方法是在创建视图.sizeMultiplier()的同时开始加载较低分辨率的图像,然后在页面发生更改时开始加载高分辨率图像。这有助于查看页面。FragmentViewPager

或者,您可以.placeholder()在图像加载时使用一段时间,这样它就不是空白空间,而是那里的“东西”。

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

也看看Glide 问题,也许你会发现一些有用的东西。

于 2015-06-25T23:15:05.293 回答