DiskCache -- 一个封装DiskLruCache的缓存工具类

DiskCache -- 一个封装DiskLruCache的缓存工具类,第1张

默认的缓存路径: /sdcard/Android/data/(应用包名)/cache/diskcache

默认的缓存大小: 50M

该工具者游类使用了DiskLruCache,所首坦销以要在build.gradle中添加:

dependencies {

implementation 'com.jakewharton:disklrucache:2.0.2'

}

具体实现信哗方式请看 源码

大家好,之前我们讲解了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的实现原理。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12166674.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存