本來是應(yīng)該分析 CacheInterceptor 緩存攔截器的衙传,考慮到這需要對OkHttp的緩存 Cache 有一定的了解千扔,所以先分析 Cache 之后再對 CacheInterceptor 緩存攔截器進(jìn)行分析捉邢。
Cache緩存我的理解就是節(jié)省客服端下一次請求網(wǎng)絡(luò)的時間播急,更快的展示數(shù)據(jù)乳丰。
我們先看下是怎么樣使用這個功能的:
OkHttpClient client = new OkHttpClient.Builder()
.cache(new Cache(new File("cache"),24*1024*1024))
.build();
調(diào)用了 OkHttpClient 的內(nèi)部類 Builder 的 cache() 方法,并傳入了一個 Cache 對象霎桅。 可以明白如果要使用緩存,只需要在創(chuàng)建 OkHttpClient 對象時配置 Cache 類就行了讨永。
接下來看下實(shí)例化 Cache 的構(gòu)造方法傳入?yún)?shù):
通過這個構(gòu)造方法就可以設(shè)置好緩存路勁和大小滔驶。
接下來我們繼續(xù)到 Cache 類的源碼中去查看:
在 Cache 的源碼上部分看到創(chuàng)建好了一個 InternalCache 對象,那這個 InternalCache 是個什么對象呢卿闹,點(diǎn)擊過去:
發(fā)現(xiàn)其實(shí)就是一個接口揭糕,在這接口中很多的方法(get,put锻霎,remove著角,update等等)。
這也就明白了這個 InternalCache 接口的所有方法實(shí)現(xiàn)都是通過 Cache 類來進(jìn)行實(shí)現(xiàn)的旋恼。
Cache的put方法
這是 put 方法的前面部分吏口,繼續(xù)看后面部分
后面部分東西還是挺多的,所以就以這種標(biāo)號的方式進(jìn)行分析,如下:
1:Entry 就是需要寫入緩存的內(nèi)容冰更。
到源碼中去查看:
image.png
可以看到 Entry 是一個 final 類产徊,里面包含了請求的一些參數(shù)(url,請求頭蜀细,請求方式舟铜,響應(yīng)頭等等),這個 Entry 類其實(shí)就是OkHttp把緩存中所需要的屬性進(jìn)行了封裝奠衔,成了一個包裝類谆刨,以便于我們進(jìn)行緩存。
2:DiskLruCache(緩存算法)——從而也就知道了OkHttp中的緩存是通過DiskLruCache實(shí)現(xiàn)的归斤。
Editor(DiskLruCache.Editor) 是DiskLruCache的內(nèi)部類痊夭,主要是用于寫入的。
3:cache其實(shí)就是一個DiskLruCache對象
image.png
4:key(...)方法脏里,到這個方法的源碼
image.png
可以清楚這個key()方法就是將請求的URL通過MD5的加密生兆,然后得到加密后的十六進(jìn)制的值。然后這個值也就是接下來緩存的key值。
5:cache.edit(...) 就是調(diào)用了DiskLruCache的edit()然后返回了Editor(DiskLruCache.Editor)對象
image.png
6:entry.writeTo(...) 剛剛知道entry就是緩存需要寫入的部分鸦难,然后調(diào)用writeTo()這個方法根吁。可以看看這個方法
image.png
image.png
image.png
可以知道在這個writeTo()方法中合蔽,就是把請求緩存寫入磁盤击敌。不僅僅緩存了響應(yīng)的頭部信息還緩存了請求的頭部信息。
在 "6" 中我們發(fā)下已近對請求的頭部響應(yīng)的頭部都進(jìn)了緩存拴事,那關(guān)鍵的響應(yīng)體Response的緩存呢沃斤?就是接下來的 "7" 了。
7:源碼是 return new CacheRequestImpl(editor);
image.png
知道這個put是返回了一個CacheRequest接口對象
image.png
在CacheRequestImpl類中實(shí)現(xiàn)了這個CacheRequest接口
image.png
那CacheRequestImpl類中為什么要去實(shí)現(xiàn)了這個CacheRequest接口呢刃宵,這就和 CacheInterceptor 緩存攔截器有關(guān)聯(lián)了衡瓶。主要是通過這個CacheRequest接口暴露給CacheInterceptor 緩存攔截器的,然后緩存攔截器就可以直接通過CacheRequestImpl實(shí)現(xiàn)類來更新和寫入緩存數(shù)據(jù)牲证。
到這個這個Cache的put方法都分析完了
put方法總結(jié)
1:首先判斷請求的請求方式是否符合緩存要求GET
2:創(chuàng)建以一個Entry對象哮针,包裝了用于緩存所需要的信息(url,頭部等等)
3:使用到DiskLruCache來進(jìn)行緩存的實(shí)際寫入
4:返回了一個CacheRequestImpl對象坦袍,這個對象主要是用于CacheInterceptor緩存攔截器的