要想更好掌握Glide,既要知其然又要知其所以然,所以让我们跟着郭大侠一起读读Glide的源码吧
因为博文太长,不写了,直接贴出郭大侠原文地址
http://blog.youkuaiyun.com/guolin_blog/article/details/53939176
http://blog.youkuaiyun.com/guolin_blog/article/details/54895665
这两篇文章需要学习的知识总结下
缓存Key
既然是缓存功能,就必然会有用于进行缓存的Key。Glide的缓存Key生成规则非常繁琐,决定缓存Key的参数竟然有10个之多。
即使你用override()方法改变了一下图片的width或者height,也会生成一个完全不同的缓存Key
硬盘缓存
第一篇文章中我们就使用过硬盘缓存的功能了。当时为了禁止Glide对图片进行硬盘缓存而使用了如下代码
Glide.with(this)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(imageView);
diskCacheStrategy()个方法基本上就是Glide硬盘缓存功能的一切,它可以接收四种参数
- DiskCacheStrategy.NONE: 表示不缓存任何内容
- DiskCacheStrategy.SOURCE: 表示只缓存原始图片
- DiskCacheStrategy.RESULT: 表示只缓存转换过后的图片(默认选项)
- DiskCacheStrategy.ALL : 表示既缓存原始图片,也缓存转换过后的图片
有一个概念大家需要了解,就是当我们使用Glide去加载一张图片的时候,Glide默认并不会将原始图片展示出来,而是会对图片进行压缩和转换(我们会在后面学习这方面的内容)。总之就是经过种种一系列操作之后得到的图片,就叫转换过后的图片。而Glide默认情况下在硬盘缓存的就是转换过后的图片,我们通过调用diskCacheStrategy()方法则可以改变这一默认行为
内存缓存
默认情况下,Glide自动就是开启内存缓存的。也就是说,当我们使用Glide加载了一张图片之后,这张图片就会被缓存到内存当中,只要在它还没从内存中被清除之前,下次使用Glide再加载这张图片都会直接从内存当中读取,而不用重新从网络或硬盘上读取了,这样无疑就可以大幅度提升图片的加载效率。比方说你在一个RecyclerView当中反复上下滑动,RecyclerView中只要是Glide加载过的图片都可以直接从内存当中迅速读取并展示出来,从而大大提升了用户体验
如果你有什么特殊的原因需要禁用内存缓存功能,Glide对此提供了接口
Glide.with(this)
.load(url)
.skipMemoryCache(true)
.into(imageView);
只需要调用skipMemoryCache()方法并传入true,就表示禁用掉Glide的内存缓存功能
郭大神对内存缓存的源码分析,概括一下来说,就是如果能从内存缓存当中读取到要加载的图片,那么就直接进行回调,如果读取不到的话,才会开启线程执行后面的图片加载逻辑
高级技巧
如果图片的资源图片都放在云端,而云端为了对图片资源进行保护,会在图片url地址的基础之上再加上一个token参数。也就是说,一张图片的url地址可能会是如下格式:
使用Glide加载这张图片的话,也就会使用这个url地址来组成缓存Key
但是接下来问题就来了,token作为一个验证身份的参数并不是一成不变的,很有可能时时刻刻都在变化。而如果token变了,那么图片的url也就跟着变了,图片url变了,缓存Key也就跟着变了。结果就造成了,明明是同一张图片,就因为token不断在改变,导致Glide的缓存功能完全失效了
解决办法是创建一个MyGlideUrl继承自GlideUrl:
public class MyGlideUrl extends GlideUrl {
private String mUrl;
public MyGlideUrl(String url) {
super(url);
mUrl = url;
}
@Override
public String getCacheKey() {
return mUrl.replace(findTokenParam(), "");
}
private String findTokenParam() {
String tokenParam = "";
int tokenKeyIndex = mUrl.indexOf("?token=") >= 0 ? mUrl.indexOf("?token=") : mUrl.indexOf("&token=");
if (tokenKeyIndex != -1) {
int nextAndIndex = mUrl.indexOf("&", tokenKeyIndex + 1);
if (nextAndIndex != -1) {
tokenParam = mUrl.substring(tokenKeyIndex + 1, nextAndIndex + 1);
} else {
tokenParam = mUrl.substring(tokenKeyIndex);
}
}
return tokenParam;
}
}
这里我们重写了getCacheKey()方法,在里面加入了一段逻辑用于将图片url地址中token参数的这一部分移除掉。这样getCacheKey()方法得到的就是一个没有token参数的url地址,从而不管token怎么变化,最终Glide的缓存Key都是固定不变的了
使用方法改为
Glide.with(this)
.load(new MyGlideUrl(url))
.into(imageView);