Okhttp解析(五)缓存的处理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Okhttp解析(五)缓存的处理相关的知识,希望对你有一定的参考价值。
参考技术A大家好,之前我们讲解了Okhttp网络数据请求相关的内容,这一节我们讲讲数据缓存的处理。本节按以下内容讲解Okhttp缓存相关的内容。
缓存的使用场景很多,通过它可以将数据通过一定的规则存储起来,再次请求数据的时候就可以快速从缓存中读取了,缓存有以下优势。
HTTP本身提供了一套缓存相关的机制。这套机制定义了相关的字段和规则,用来客户端和服务端进行缓存相关的协商,如响应的数据是否需要缓存,缓存有效期,缓存是否有效,服务器端给出指示,而客户端则根据服务端的指示做具体的缓存更新和读取缓存工作。http缓存可以分为两类:
强制缓存,在缓存数据未失效的情况下,可以直接使用缓存数据,有两个字段Expires和Cache-Control用于标明失效规则。
表示过期时间,由服务端返回。那么下次请求数据时,判断这个Expires过期时间是否已经过了,如果还没有到过期时间,则使用缓存,如果过了过期时间,则重新请求服务器的数据。Expires格式如下:
不过因为服务器和客户端的时间并不是同步的,用一个绝对时间作为过期的标记并不是很明智,所以HTTP1.1之后更多的是Cache-Control,它的控制更加灵活。
表示缓存的控制,有服务端返回。它有以下几个取值:
默认情况下是private,也就是不能共享的。Cache-Control格式如下:
对比缓存,表示需要和服务端进行相关信息的对比,由服务器决定是使用缓存还是最新内容,如果服务器判定使用缓存,返回响应吗304,判定使用最新内容,则返回响应码200和最新数据。对比缓存的判定字段有两组:
ETag表示资源的一种标识信息,用于标识某个资源,由服务端返回,优先级更高。格式如下:
然后客户端再次请求时,加入字段If-None-Match,格式如下:
服务端收到请求的该字段时(之前的Etag值),和资源的唯一标识进行对比,如果相同,说明没有改动,则返回状态码304,如果不同,说明资源被改过了,则返回状态码200和整个内容数据。
Last-Modified表示资源的最近修改时间,由服务端返回,优先级更低。格式如下:
Last-Modified
由服务器返回,表示响应的数据最近修改的时间。
If-Modified-Since
由客户端请求,表示询问服务器这个时间是不是上次修改的时间。如果服务端该资源的修改时间小于等于If-Modified-Since指定的时间,说明资源没有改动,返回响应状态码304,可以使用缓存。如果服务端该资源的修改时间大于If-Modified-Since指定的时间,说明资源又有改动了,则返回响应状态码200和最新数据给客户端,客户端使用响应返回的最新数据。
Last-Modified字段的值(服务端返回的资源上次修改时间),常常被用于客户端下次请求时的If-Modified-Since字段中。
HTTP的缓存规则是优先考虑强制缓存,然后考虑对比缓存。
Okhttp缓存相关的类有如下:
要开启使用Okhttp的缓存其实很简单,只需要给OkHttpClient对象设置一个Cache对象即可,创建一个Cache时指定缓存保存的目录和缓存最大的大小即可。
那么下面我们来看看Okhttp缓存执行的大概流程
Okhttp的缓存流程分为读取缓存和存储缓存两个过程,我们分别分析。
读取使用缓存的流程从HttpEngine的sendRequest发送请求开始。
接下来我们分析
从Cache的get方法开始。它按以下步骤进行。
如果存在缓存的话,在指定的缓存目录中,会有两个文件“****.0”和“****.1”,分别存储某个请求缓存的响应头和响应体信息。(“****”是url的md5加密值)对应的ENTRY_METADATA响应头和ENTRY_BODY响应体。缓存的读取其实是由DiskLruCache来读取的,DiskLruCache是支持Lru(最近最少访问)规则的用于磁盘存储的类,对应LruCache内存存储。它在存储的内容超过指定值之后,就会根据最近最少访问的规则,把最近最少访问的数据移除,以达到总大小不超过限制的目的。
接下来我们分析CacheStrategy缓存策略是怎么判定的。
直接看CacheStrategy的get方法。缓存策略是由请求和缓存响应共同决定的。
接来下我们看看CacheControl类里有些什么。
可以发现,它就是用于描述响应的缓存控制信息。
然后我们再看看Okhttp存储缓存是怎么进行的。
存储缓存的流程从HttpEngine的readResponse发送请求开始的。
可以看到这里先通过maybeCache写入了响应头信息,再通过cacheWritingResponse写入了响应体信息。我们再进去看Cache的put方法实现。
我们继续看Cache的writeTo方法,可以看到是写入一些响应头信息。
到这里Okhttp缓存的读取和存储流程我们就清楚了。可以说,缓存的使用策略基本都是按照HTTP的缓存定义来实现的,所以对HTTP缓存相关字段的理解是很重要的。然后关于DiskLruCache是如何管理缓存文件的,这个其实也很好理解,首先的原则就是按照LRU这种最近最少使用删除的原则,当总的大小超过限定大小后,删除最近最少使用的缓存文件,它的LRU算法是使用LinkedHashMap进行维护的,这样来保证,保留的缓存文件都是更常使用的。具体实现大家可以分析DiskLruCache和LinkedHashMap的实现原理。
以上是关于Okhttp解析(五)缓存的处理的主要内容,如果未能解决你的问题,请参考以下文章