OkHttp Cache缓存put 源码分析

OkHttp Cache缓存put 源码分析_第1张图片
image

本来是应该分析 CacheInterceptor 缓存拦截器的,考虑到这需要对OkHttp的缓存 Cache 有一定的了解,所以先分析 Cache 之后再对 CacheInterceptor 缓存拦截器进行分析。

Cache缓存我的理解就是节省客服端下一次请求网络的时间,更快的展示数据。

我们先看下是怎么样使用这个功能的:

OkHttpClient client = new OkHttpClient.Builder()
                .cache(new Cache(new File("cache"),24*1024*1024))
                .build();

调用了 OkHttpClient 的内部类 Buildercache() 方法,并传入了一个 Cache 对象。 可以明白如果要使用缓存,只需要在创建 OkHttpClient 对象时配置 Cache 类就行了。

接下来看下实例化 Cache 的构造方法传入参数:


image.png

通过这个构造方法就可以设置好缓存路劲和大小。

接下来我们继续到 Cache 类的源码中去查看:


OkHttp Cache缓存put 源码分析_第2张图片
image.png

Cache 的源码上部分看到创建好了一个 InternalCache 对象,那这个 InternalCache 是个什么对象呢,点击过去:


OkHttp Cache缓存put 源码分析_第3张图片
image.png

发现其实就是一个接口,在这接口中很多的方法(get,put,remove,update等等)。
这也就明白了这个 InternalCache 接口的所有方法实现都是通过 Cache 类来进行实现的。

Cache的put方法



OkHttp Cache缓存put 源码分析_第4张图片
image.png

这是 put 方法的前面部分,继续看后面部分


OkHttp Cache缓存put 源码分析_第5张图片
image.png

后面部分东西还是挺多的,所以就以这种标号的方式进行分析,如下:

1:Entry 就是需要写入缓存的内容。
到源码中去查看:

OkHttp Cache缓存put 源码分析_第6张图片
image.png

可以看到 Entry 是一个 final 类,里面包含了请求的一些参数(url,请求头,请求方式,响应头等等),这个 Entry 类其实就是OkHttp把缓存中所需要的属性进行了封装,成了一个包装类,以便于我们进行缓存。

2:DiskLruCache(缓存算法)——从而也就知道了OkHttp中的缓存是通过DiskLruCache实现的。
Editor(DiskLruCache.Editor)DiskLruCache的内部类,主要是用于写入的。

3:cache其实就是一个DiskLruCache对象

image.png

4:key(...)方法,到这个方法的源码

image.png

可以清楚这个 key()方法就是将请求的 URL通过 MD5的加密,然后得到加密后的十六进制的值。然后这个值也就是接下来缓存的 key值。

5:cache.edit(...) 就是调用了DiskLruCacheedit()然后返回了Editor(DiskLruCache.Editor)对象

OkHttp Cache缓存put 源码分析_第7张图片
image.png

6:entry.writeTo(...) 刚刚知道entry就是缓存需要写入的部分,然后调用writeTo()这个方法。可以看看这个方法

OkHttp Cache缓存put 源码分析_第8张图片
image.png

OkHttp Cache缓存put 源码分析_第9张图片
image.png

OkHttp Cache缓存put 源码分析_第10张图片
image.png

可以知道在这个 writeTo()方法中,就是把请求缓存写入磁盘。不仅仅缓存了响应的头部信息还缓存了请求的头部信息。

"6" 中我们发下已近对请求的头部响应的头部都进了缓存,那关键的响应体Response的缓存呢?就是接下来的 "7" 了。

7:源码是 return new CacheRequestImpl(editor);

image.png

知道这个 put是返回了一个 CacheRequest接口对象


OkHttp Cache缓存put 源码分析_第11张图片
image.png

CacheRequestImpl类中实现了这个 CacheRequest接口


OkHttp Cache缓存put 源码分析_第12张图片
image.png

CacheRequestImpl类中为什么要去实现了这个CacheRequest接口呢,这就和 CacheInterceptor 缓存拦截器有关联了。主要是通过这个CacheRequest接口暴露给CacheInterceptor 缓存拦截器的,然后缓存拦截器就可以直接通过CacheRequestImpl实现类来更新和写入缓存数据。

到这个这个Cacheput方法都分析完了

put方法总结

1:首先判断请求的请求方式是否符合缓存要求GET
2:创建以一个Entry对象,包装了用于缓存所需要的信息(url,头部等等)
3:使用到DiskLruCache来进行缓存的实际写入
4:返回了一个CacheRequestImpl对象,这个对象主要是用于CacheInterceptor缓存拦截器的

你可能感兴趣的:(OkHttp Cache缓存put 源码分析)