前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Glide优化

Glide优化

作者头像
六月的雨
发布2020-03-27 00:08:41
2.3K0
发布2020-03-27 00:08:41
举报
文章被收录于专栏:Android开发指南Android开发指南

几乎所有的 OOM 错误都是因为宿主应用出了问题,而不是 Glide 本身。 应用里两种常见的 OOM 错误分别是: 过大的内存分配 (Excessively large allocations) 内存泄露(Memory leaks, 被分配的内存没有被释放)

  • 引入largeHeap属性,让系统为App分配更多的独立内存。
  • 禁止Glide内存缓存。设置skipMemoryCache(true)。
  • 自定义GlideModule。设置MemoryCache和BitmapPool大小。
  • 升级到Glide4.0,使用asDrawable代替asBitmap,drawable更省内存。
  • ImageView的scaleType为fitXY时,改为fitCenter/centerCrop/fitStart/fitEnd显示。
  • 不使用application作为context。当context为application时,会把imageView是生命周期延长到整个运行过程中,imageView不能被回收,从而造成OOM异常。
  • 使用application作为context。但是对ImageView使用弱引用或软引用,尽量使用SoftReference,当内存不足时,将及时回收无用的ImageView。
  • 当列表在滑动的时候,调用Glide的pauseRequests()取消请求,滑动停止时,调用resumeRequests()恢复请求。
代码语言:javascript
复制
if (view.getContext() != null) {
        switch (scrollState) {
            case SCROLL_STATE_IDLE:
                Glide.with(view.getContext()).resumeRequests();
                break;
            case SCROLL_STATE_TOUCH_SCROLL:
            case SCROLL_STATE_FLING:
                Glide.with(view.getContext()).pauseRequests();
                break;
        }
    }
  • Try catch某些大内存分配的操作。考虑在catch里面尝试一次降级的内存分配操作。例如decode bitmap的时候,catch到OOM,可以尝试把采样比例再增加一倍之后,再次尝试decode。
  • BitmapFactory.Options和BitmapFactory.decodeStream获取原始图片的宽、高,绕过Java层加载Bitmap,再调用Glide的override(width,height)控制显示。
  • 图片局部加载。参考:SubsamplingScaleImageView,先将图片下载到本地,然后去加载,只加载当前可视区域,在手指拖动的时候再去加载另外的区域。
  • onTrimMemory,调用 Glide.cleanMemroy() 清理掉所有的内存缓存。(内部是LruBitmapPool )
  • 如果是处于 lowMemory 的时候,将图片的 DecodeFormat 设置为 RGB_565
  • 使用glide自己的圆角图片。bitmapTransfrom

优化GIF

FrameSequence是Android framework中里的一个工具包。 它封装了: giflib (gif编解码库c++ ),并提供Java API播放gif。使用它要比glide加载GIF效果效果要好,glide加载加载GIF图片CPU占用高,并且内存占用一直在增加。使用FrameSequence库就可以解决,不过每次判断去怎么加载很麻烦,可以使用glide的AppGlideModule apt注解解析器来自动生成代码。判断GIF图片时将InputStream转成FrameSequenceDrawable解析。这个还可以做播放Webp动画。

代码语言:javascript
复制
@GlideModule
public class GifGlideModule extends AppGlideModule {
    @Override
    public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
        super.registerComponents(context, glide, registry);
        registry.append(Registry.BUCKET_GIF,
                InputStream.class,
                FrameSequenceDrawable.class, new GifDecoder(glide.getBitmapPool()));
    }
}

Glide加载Gif图片的原理:将gif根据每一帧解析成很张图片,然后在依次设置给ImageView。

FrameSequenceDrawable原理 利用了两个Bitmap对象,其中一个用于绘制到屏幕上,另外一个用于解析下一张要展示的图片,利用了HandlerThread在子线程解析,每次解析的时候获取上一张图片的展示时间,然后使用Drawable自身的scheduleSelf方法在指定时间替换图片,在达到替换时间时,会调用draw方法,在draw之前先去子线程解析下一张要展示的图片,然后重复这个步骤,直到播放结束或者一直播放。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-05-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 优化GIF
相关产品与服务
云直播
云直播(Cloud Streaming Services,CSS)为您提供极速、稳定、专业的云端直播处理服务,根据业务的不同直播场景需求,云直播提供了标准直播、快直播、云导播台三种服务,分别针对大规模实时观看、超低延时直播、便捷云端导播的场景,配合腾讯云视立方·直播 SDK,为您提供一站式的音视频直播解决方案。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档