图片框架-Glide的源码和缓存原理简述

比较流行的有ImageLoader,Picasso,Fresco,Glide。

1 ImageLoader是很早的图片加载框架,支持图片下载进度的监听,支持View滚动过程中暂停加载。支持多种缓存策略比如最大先删除,最少使用先删除等。

2 Picasso简洁轻量,支持图片缓存使用的监控,支持优先级处理,支持延迟加载,自己不参与本地缓存而是交给OkHttp去实现。

3 Fresco框架较大,使用比较繁琐,支持Gif图片,支持流式显示,类似于网页模糊渐进式显示图片,两个内存缓存和一个Native缓存构建三级缓存。

4 Glide 支持图片缓存,支持Gif,Video。支持优先级处理,与Activity和Fragment生命周期同步,图片默认是RGB_565,质量较差内存更小。功能更为丰富。

项目中用的最多的是Glide:

Glide基本用法with,load,into。

with传入的可以是当前上下文的对象。

load加载图片,图片可以是本地图片,应用资源的图片也可以是一张网络图片。

into传入要展示图片的控件。

with是Glide类的一个静态方法,重载方法很多可以接收

Activity,Fragment,Context。

with方法里面,首先会调用RequestManagerRetriever的静态get方法得到RequestManagerRetriver对象。然后再调用该对象的get方法获取RequestManager对象。静态get方法中也有很多重载方法,主要分为传入Application参数和非Application参数,传入Application参数是最简单的情况,Glide只要持保和整个应用生命周期同步。

非Application参数不管是Activity,Fragment,最终都会向当前Activity传入一个隐藏的Fragment,因为Glide需要监控Activity的生命周期,Fragment依赖Activity生命周期并且是同步的,通过这个隐藏的Fragment就监听到Activity生命周期。

load方法,with方法返回的是一个RequestManager对象,所以load方法在RequestManager类中,load方法也有很多重载,支持本地图片,内存图片,网络图片,只看加载url的load方法。首先调用了fromString方法,再调用load方法,传入图片url,fromString方法里调用了loadGeneric方法,这个方法创建并返回了DrawableTypeRequest对象。

DrawableTypeRequest并没有load方法,load在DrawableTypeRequest的父类DrawableTypeRequestBuildle中。大部分操作都在这个类中,比如placeholder占位符,error,discacheStrategy等。

into方法是Glide图片加载流程中逻辑最为复杂的方法。

into方法在DrawableTypeRequestBuilder类中,里面调用了super.into方法,真正的实现在DrawableTypeRequestBuilder的父类GenericRequestBuilder中,这个类包括了网络请求,图片解析,图片解码,bitmap生成,缓存处理,图片压缩等大量逻辑操作,最后的最后才将图片展示出来。

最关注的是Glide缓存:Glide分为内存缓存和硬盘缓存两个模块,先从内存缓存查找再到硬盘缓存查找最后从网络请求。

每种缓存必须有一个缓存key用来查询,Glide缓存key是在Engine类load方法中实现,通过调用getId方法获取一个字符串id,这个id就是要加载图片的唯一标识。如果是网络图片就是图片的url地址。然后这个id同传入的参数构建出EngineKey也就是Glide的缓存key。

内存缓存:

1 LruCache算法缓存,最近最少使用原则,缓存原理是把最近使用的对象用强引用存储到LinkHashMap中,把最近最少使用的对象在缓存值达到一定上限之前从缓存中移除。

2 弱引用缓存,缓存原理是把正在使用的图片缓存到弱引用的HashMap中,主要防止正在使用的图片被LruCache算法回收。

硬盘缓存:缓存策略有缓存转换后的图片和原始图片,默认是缓存转换后的。缓存算法依然是LruCache是谷歌封装的DisLruCache。

如果有缓存文件的话会调用decodeFromCache从缓存中读取,如果没有调用decodeFromSource,从源头读取比如从网络获取。

遇到Glide缓存问题,项目的图片资源都是放在七牛云上面的,下载下来的图片url地址后面有一个token参数,token作为一个验证身份的参数是时刻变化的。在Glide缓存中是通过图片的url进行缓存的。结果造成了明明是一张图片,因为token的改变导致Glide缓存功能失效。

在查看源码的时候,发现Glide缓存key是在Engine类中load方法中生成的。在这个方法中通过getId()方法返回了一个字符串id,发现这个id就是图片的Url地址。然后找这个getId方法,发现在这个方法里又调用了GlideUrl类中getCacheKey方法,在这个方法里直接返回了图片的url地址,最后通过继承这个GlideUrl类重写getCacheKey方法,去掉图片的Url地址后面的token参数,然后将这个继承类传给Glide的load方法就可以解决Glide缓存问题了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

summer0012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值