Android Glide缓存策略

一、glide缓存策略

缓存在请求网络图片时能减少不必要的流量浪费。Glide 缓存分为内存缓存和硬盘缓存,这两个缓存模块的作用各不相同,内存缓存的主要作用是 防止应用重复的将图片数据读取到内存,而硬盘缓存则是防止应用重复从网络或其他地方下载和读取数据。

关于缓存,就一定涉及到缓存 key 。如何生成 key 呢?查看 KeyFactory.buildKey() 方法。一般一张网络图片的唯一标志是图片 url 地址,但是基于这张图片加载时设置的一系列规则,比如 override 设置了固定大小也会生成新的缓存 Key .

1、内存缓存
Glide 默认是开启了内存缓存,可以通过代码设置:

Glide.with(this).load(url).skipMemoryCache(true).into(iv);

skipMemoryCache() 方法传入 true,就表示禁止 Glide 的内存功能。

内存缓存经常会用到 LruCache 算法,Glide 的内存缓存用到的也是 LruCache 算法,同时也用到了一种弱引用机制,共同完成内存缓存。

追溯源码至 Engine.load() 方法,这一步开始决定是使用缓存数据还是直接重新下载图片,整个流程如下:
在这里插入图片描述
这里有个问题:LruCache 只看到了取数据的过程,那么何时会存数据呢?
A: Engine.onResourceReleased() 释放资源时,具体在于 acquire 引用计数器的作用:

当计数器>0,说明图片正在使用,存在于 activeResources 弱引用map中;
经过 release() 后,若计数器=0,说明图片不再被使用,就会调用上述方法释放资源,此时在该方法中会将当前没有使用的资源缓存到 LruCache 中。

2、磁盘缓存
Glide 禁止磁盘缓存的代码如下:

Glide.with(this).load(url).diskCacheStrategy(DiskCacheStrategy.NONE).into(iv);

先来说说几种磁盘缓存的策略:

DiskCacheStrategy.NONE:表示不缓存任何内容
DiskCacheStrategy.SOURCE:表示只缓存原始图片
DiskCacheStrategy.RESULT:表示只缓存转换后的图片(默认选项)
DiskCacheStrategy.ALL:表示既缓存原始图片,也缓存转换后的图片
注:Glide 加载一张图时,默认不会展示原图,而是会对图片进行压缩和转换,比如对图片进行尺寸压缩到 目标View大小。

磁盘缓存使用的也是 LRU 算法,对应的实现工具为 DiskLruCache ,整个处理流程接着上面内存缓存的流程开始,也即是 新开 EngineRunnable 任务加载图片,这一步会先判断是否进行过磁盘缓存,若可以则直接从磁盘缓存取,否则重新下载。流程如下:
在这里插入图片描述
关于 Glide 的缓存机制目前就到这里,简单总结就是:

若允许内存缓存,先从内存LruCache中查找,若存在则将该资源添加到 activeResouces 弱引用map中然后返回,该 map 主要用来缓存当前正在使用的资源,若不存在则判断 activeResouces 弱引用map 中是否存在,若存在则返回,每次资源处于正在使用状态,则引用计数加一,若未使用,则缓存到 LruCache 中;
若内存中不存在,若允许磁盘缓存,再从磁盘缓存中查找;
若磁盘中不存在,则直接下载,然后再根据磁盘缓存策略缓存原图或是经转换后的图到磁盘中。

二、Glide中为什么有弱引用缓存

1、弱引用
弱引用通过WeakReference类实现。 弱引用的生命周期比软引用短。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。由于垃圾回收器是一个优先级很低的线程,因此不一定会很快回收弱引用的对象。弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中(和引用队列一起使用同上面的软引用)。

应用场景:弱应用同样可用于内存敏感的缓存。

2、为什么有弱引用缓存
因为Lru算法,他是最近最少使用原则的回收策略;所以可能导致正在使用的图片被回收,如果用了弱引用的缓存,就可以保证它正在使用的时候不会被回收,这样就实现了正在使用资源与缓存资源的隔离;正在使用资源不收到Lru算法的回收影响。
而且弱引用对象,他的get(),然后赋值给强引用对象的时候,他就是多了个强引用了,就不会被回收了;当没有get的弱引用被回收了,就会进入到引用队列,对弱引用进行回收监听,当触发了回收,就立马从引用队列中获取到相应的对象加入到内存缓存中。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

互联网小熊猫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值