既然说Glide缓存那咱们得先知道缓存机制是啥?
宏观上说主要分两种缓存机制内存缓存,磁盘缓存
使用内存缓存原因:防止重复的把图片读入内存,使其内存资源浪费。
使用磁盘缓存原因:防止重复从网络上或其他途径下载和读取的数据,使其内存资源浪费。
Glide三级缓存是啥呢?
内存缓存,优先加载,速度最快
本地缓存,次优先加载,速度快
网络缓存,最后加载,速度慢,浪费流量
Glide三级缓存那原理是啥?从写入和读取缓存的角度解析 Glide 的缓存
弱引用是啥?看此链接[https://blog.csdn.net/weixin_44819566/article/details/111170907]
映射是啥?看此链接[https://blog.csdn.net/mcryeasy/article/details/86741781]
双向链表是啥?看此链接[https://baike.baidu.com/item/双向链表/2968731?fr=aladdin]
HashMap是哈?看此链接https://www.jianshu.com/p/dde9b12343c1
读取:读取缓存顺序如下:
LruCache算法缓存 ------>到弱引用缓存----->进入磁盘缓存
加载图片先从LruCache 去找看有没有,如果有就放入WeakReference,如果没有执行下一步去WeakReference中找有没有,有的话拿出来用,没有在接着往下去找/磁盘缓存或者网路缓存
写入:写入缓存顺序如下:
弱引用缓存 ------>LruCache算法缓存----->进入磁盘缓存
写入先将图片存入弱引用缓存,然后acpuired(图片引用计数器)变量来记录图片被用的次数。
acpuired > 0 :图片正在使用。
acpuired = 0 :图片已经没有使用,然后接下来释放资源,先将图片从缓存中移除,put到LruResourceCache
这样就做到了 如果图片正在使用就要引用缓存,图片已经没有使用就去LruCache算法缓存。
LruCache是啥意思呢?近期最少使用算法
按从近期访问最少到近期访问最多的顺序(即访问顺序)来保存元素,LinkedHashMap提供了LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)构造函数,该哈希映射的迭代顺序就是最后访问其条目的顺序,这种映射很适合构建LRU缓存。
以上是摘取别人的解释转换我的话语就是提前设定一个固定的缓存A 大小为10M,当缓存达到10M 将以前的旧数据移除,防止oom,LruCache内部就是上面的LinkedHashMap通过映射存取数据
那么LinkedHashMap有具体是啥呢?
LinkedHashMap继承于HashMap,HashMap是无序的,当我们想有顺序地去存储key-value时,就需要使用LinkedHashMap了且默认为插入顺序。内部利用的就是双向链表结构。
那在这里就可以提出一个问题,同一张照片放在不同尺寸的view控件上 Glide会只拿一张图片缓存使用展示不同的view控件上吗?
答案是不会的,如果仔细读过我以前的Glide解析会发现这个里面存储的值需要宽高两个参数,证明这个宽高是生成key的必要条件,Glide内部如果是不同的尺寸Glide会重新加载一次,缓存两张图片!
那接着可以提出新的问题,如果Glide正在运行,突然杀死页面(就是关闭)那这个页面会内存泄露吗?
不会
这个地方你就可以考虑关联到Glide的生命周期是绑定的,当时前面讲的时候分两种 ,
一种是在常用的Activity和Fragment上面:RequestManagerFragment(透明Fragment)加入FragmentManager中进行感知生命周期。
另一种在没有生命周期的情况:,会采用Application 的生命周期贯穿整个应用,始终跟着applicationManager贯穿整个应用。
Glide磁盘缓存的读写
如果前面两种缓存都没有那么就进入磁盘缓存,内存缓存有助于加快对最近查看过的位图的访问,但您不能依赖于此缓存中保留的图片,如果你看了一个比较大数据集的组件很容易将内存缓存填满。您的应用可能被其他任务(如电话)中断等,而在后台时,应用可能会被终止,而内存缓存则会销毁。用户恢复操作后,您的应用必须重新处理每张图片所以必须磁盘缓存(DiskLruCache) 。DiskLruCache整体的思想跟LruCache是一样的,也是利用了LinkedHashMap,但是DiskLruCache做了很多保护措施,DiskLruCache在各种对文件的操作上都将读写分开,为了怕写失败等情况,都是先尝试写在一个中间文件,成功再重命名回目标文件,其实DiskLruCache并没有限制数据的缓存位置,可以自由地进行设定,但是通常情况下多数应用程序都会将缓存的位置选择为 /sdcard/Android/data/<application package>/cache 这个路径。选择在这个位置有两点好处:
第一,这是存储在SD卡上的,因此即使缓存再多的数据也不会对手机的内置存储空间有任何影响,只要SD卡空间足够就行。
第二,这个路径被Android系统认定为应用程序的缓存路径,当程序被卸载的时候,这里的数据也会一起被清除掉,这样就不会出现删除程序之后手机上还有很多残留数据的问题。
在这推荐郭霖大神的一篇缓存博客:这里面说明了当上传七牛云toekn 变化而导致的图片缓存不能使用的解决办法
https://guolin.blog.csdn.net/article/details/54895665
借鉴链接:[https://blog.csdn.net/qq_33565218/article/details/98970980]
借鉴链接:[https://guolin.blog.csdn.net/category_9268670.html]
.