前言
在Android開發(fā)中我們經(jīng)常要進行各種網(wǎng)絡(luò)訪問,比如查看各類新聞、查看各種圖片。但有一種情形就是我們每次重復(fù)發(fā)送的網(wǎng)絡(luò)請求其實返回的內(nèi)容都是一樣的。比如一個電影類APP,每一次向服務(wù)器申請某個電影的相關(guān)信息,如封面、簡介、演員表等等,它們的信息都是一樣的。顯然,這樣有點浪費資源,最主要的是這些重復(fù)的請求產(chǎn)生了沒有必要的流量。流量、流量、流量!!!重要的事情說三遍!剛開始工作的我也不懂,后來才發(fā)現(xiàn),流量是要付費的,而且超貴,公司那么小,一個月要支付寬帶運營商巨額的流量費用。所以領(lǐng)導(dǎo)們都想方設(shè)法地要節(jié)省帶寬。
其實這在整個軟件開發(fā)中隨時可見,解決的方法就是把重復(fù)請求的數(shù)據(jù)緩存在本地,并設(shè)置超時時間,在規(guī)定時間內(nèi),客戶端不再向遠程請求數(shù)據(jù),而是直接從本地緩存中取數(shù)據(jù)。這樣一來提高了響應(yīng)速度,二來節(jié)省了網(wǎng)絡(luò)帶寬(也就是節(jié)省了錢)。 本文就是講解在OKHTTP中如何配置緩存。
HTTP協(xié)議中緩存相關(guān)
為了更好的講解OKHTTP怎么設(shè)置緩存,我們追根溯源先從瀏覽器的緩存說起,這樣后面的OKHTTP緩存內(nèi)容自然更加好理解。
我這部分內(nèi)容也是經(jīng)網(wǎng)絡(luò)上查閱,這一篇寫得很詳細瀏覽器 HTTP 協(xié)議緩存機制詳解。以下內(nèi)容基本出自于此文章。
緩存分類
http請求有服務(wù)端和客戶端之分。因此緩存也可以分為兩個類型服務(wù)端側(cè)和客戶端側(cè)。
服務(wù)端側(cè)緩存
常見的服務(wù)端有Ngix和Apache。服務(wù)端緩存又分為代理服務(wù)器緩存和反向代理服務(wù)器緩存。常見的CDN就是服務(wù)器緩存。這個好理解,當(dāng)瀏覽器重復(fù)訪問一張圖片地址時,CDN會判斷這個請求有沒有緩存,如果有的話就直接返回這個緩存的請求回復(fù),而不再需要讓請求到達真正的服務(wù)地址,這么做的目的是減輕服務(wù)端的運算壓力。
客戶端側(cè)緩存
客戶端主要指瀏覽器(如IE、Chrome等),當(dāng)然包括我們的OKHTTPClient.客戶端第一次請求網(wǎng)絡(luò)時,服務(wù)器返回回復(fù)信息。如果數(shù)據(jù)正常的話,客戶端緩存在本地的緩存目錄。當(dāng)客戶端再次訪問同一個地址時,客戶端會檢測本地有沒有緩存,如果有緩存的話,數(shù)據(jù)是有沒有過期,如果沒有過期的話則直接運用緩存內(nèi)容。
而我們講的就是客戶端的緩存。
緩存中重要的概念
Cache-Control
Cache-Control是什么呢?先別急, 我們先用觀察一個結(jié)果,用Fiddler監(jiān)聽瀏覽器訪問http://blog.csdn.net/briblue。如下圖:
HTTP/1.1 200 OK
Server: openresty
Date: Mon, 24 Oct 2016 09:00:34 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=20
Vary: Accept-Encoding
Cache-Control: private
X-Powered-By: PHP 5.4.28
Content-Encoding: gzip
可以看到頭信息中有這么一行:
Cache-Control: private
Cache-control是由服務(wù)器返回的Response中添加的頭信息,它的目的是告訴客戶端是要從本地讀取緩存還是直接從服務(wù)器摘取消息。它有不同的值,每一個值有不同的作用。
max-age:這個參數(shù)告訴瀏覽器將頁面緩存多長時間,超過這個時間后才再次向服務(wù)器發(fā)起請求檢查頁面是否有更新。對于靜態(tài)的頁面,比如圖片、CSS、Javascript,一般都不大變更,因此通常我們將存儲這些內(nèi)容的時間設(shè)置為較長的時間,這樣瀏覽器會不會向瀏覽器反復(fù)發(fā)起請求,也不會去檢查是否更新了。
s-maxage:這個參數(shù)告訴緩存服務(wù)器(proxy,如Squid)的緩存頁面的時間。如果不單獨指定,緩存服務(wù)器將使用max-age。對于動態(tài)內(nèi)容(比如文檔的查看頁面),我們可告訴瀏覽器很快就過時了(max-age=0),并告訴緩存服務(wù)器(Squid)保留內(nèi)容一段時間(比如,s-maxage=7200)。一旦我們更新文檔,我們將告訴Squid清除老的緩存版本。
must-revalidate:這告訴瀏覽器,一旦緩存的內(nèi)容過期,一定要向服務(wù)器詢問是否有新版本。
proxy-revalidate:proxy上的緩存一旦過期,一定要向服務(wù)器詢問是否有新版本。
no-cache:不做緩存。
no-store:數(shù)據(jù)不在硬盤中臨時保存,這對需要保密的內(nèi)容比較重要。
public:告訴緩存服務(wù)器, 即便是對于不該緩存的內(nèi)容也緩存起來,比如當(dāng)用戶已經(jīng)認證的時候。所有的靜態(tài)內(nèi)容(圖片、Javascript、CSS等)應(yīng)該是public的。
private:告訴proxy不要緩存,但是瀏覽器可使用private cache進行緩存。一般登錄后的個性化頁面是private的。
no-transform: 告訴proxy不進行轉(zhuǎn)換,比如告訴手機瀏覽器不要下載某些圖片。
max-stale指示客戶機可以接收超出超時期間的響應(yīng)消息。如果指定max-stale消息的值,那么客戶機可以接收超出超時期指定值之內(nèi)的響應(yīng)消息。
我們上面的例子是Cache-Control:private。說明服務(wù)器希望客戶端不要緩存消息,但是可以進行private cache方法進行緩存。這是因為http://blog.csdn.net/briblue是我的博客頁面,與用戶系統(tǒng)相關(guān),所以為了安全起見,建議用private cache的方式緩存。
在OKHttp開發(fā)中我們常見到的有下面幾個:
- max-age
- no-cache
- max-stale
expires
expires的效果等同于Cache-Control,不過它是Http 1.0的內(nèi)容,它的作用是告訴瀏覽器緩存的過期時間,在此時間內(nèi)瀏覽器不需要直接訪問服務(wù)器地址直接用緩存內(nèi)容就好了。 expires最大的問題在于如果服務(wù)器時間和本地瀏覽器相差過大的問題。那樣誤差就很大。所以基本上用Cache-Control:max-age=多少秒的形式代替。
Last-Modified/If-Modified-Since
這個需要配合Cache-Control使用
- Last-Modified:標示這個響應(yīng)資源的最后修改時間。web服務(wù)器在響應(yīng)請求時,告訴瀏覽器資源的最后修改時間。
- If-Modified-Since:當(dāng)資源過期時(使用Cache-Control標識的max-age),發(fā)現(xiàn)資源具有Last-Modified聲明,則再次向web服務(wù)器請求時帶上頭 If-Modified-Since,表示請求時間。web服務(wù)器收到請求后發(fā)現(xiàn)有頭If-Modified-Since 則與被請求資源的最后修改時間進行比對。若最后修改時間較新,說明資源又被改動過,則響應(yīng)整片資源內(nèi)容(寫在響應(yīng)消息包體內(nèi)),HTTP 200;若最后修改時間較舊,說明資源無新修改,則響應(yīng)HTTP 304 (無需包體,節(jié)省瀏覽),告知瀏覽器繼續(xù)使用所保存的cache。
Etag/If-None-Match
這個也需要配合Cache-Control使用
Etag對應(yīng)請求的資源在服務(wù)器中的唯一標識(具體規(guī)則由服務(wù)器決定),比如一張圖片,它在服務(wù)器中的標識為ETag: W/”ACXbWXd1n0CGMtAd65PcoA==”。
If-None-Match 如果瀏覽器在Cache-Control:max-age=60設(shè)置的時間超時后,發(fā)現(xiàn)消息頭中還設(shè)置了Etag值。然后,瀏覽器會再次向服務(wù)器請求數(shù)據(jù)并添加In-None-Match消息頭,它的值就是之前Etag值。服務(wù)器通過Etag來定位資源文件,根據(jù)它是否更新的情況給瀏覽器返回200或者是304。
Etag機制比Last-Modified精確度更高,如果兩者同時設(shè)置的話,Etag優(yōu)先級更高。
Pragma
Pragma頭域用來包含實現(xiàn)特定的指令,最常用的是Pragma:no-cache。
在HTTP/1.1協(xié)議中,它的含義和Cache- Control:no-cache相同。
以上是Http中關(guān)于緩存的相關(guān)信息。接下來我們進入主題,如何配置OkHttp的緩存。
OKHTTP之Cache
OKHTTP如果要設(shè)置緩存,首要的條件就是設(shè)置一個緩存文件夾,在Android中為了安全起見,一般設(shè)置為私密數(shù)據(jù)空間。通過getExternalCacheDir()獲取。如然后通過調(diào)用OKHttpClient.Builder中的cache()方法。如下面代碼所示:
//緩存文件夾
File cacheFile = new File(getExternalCacheDir().toString(),"cache");
//緩存大小為10M
int cacheSize = 10 * 1024 * 1024;
//創(chuàng)建緩存對象
Cache cache = new Cache(cacheFile,cacheSize);
OkHttpClient client = new OkHttpClient.Builder()
.cache(cache)
.build();
設(shè)置好Cache我們就可以正常訪問了。我們可以通過獲取到的Response對象拿到它正常的消息和緩存的消息。
Response的消息有兩種類型,CacheResponse和NetworkResponse。CacheResponse代表從緩存取到的消息,NetworkResponse代表直接從服務(wù)端返回的消息。示例代碼如下:
private void testCache(){
//緩存文件夾
File cacheFile = new File(getExternalCacheDir().toString(),"cache");
//緩存大小為10M
int cacheSize = 10 * 1024 * 1024;
//創(chuàng)建緩存對象
final Cache cache = new Cache(cacheFile,cacheSize);
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient client = new OkHttpClient.Builder()
.cache(cache)
.build();
//官方的一個示例的url
String url = "http://publicobject.com/helloworld.txt";
Request request = new Request.Builder()
.url(url)
.build();
Call call1 = client.newCall(request);
Response response1 = null;
try {
//第一次網(wǎng)絡(luò)請求
response1 = call1.execute();
Log.i(TAG, "testCache: response1 :"+response1.body().string());
Log.i(TAG, "testCache: response1 cache :"+response1.cacheResponse());
Log.i(TAG, "testCache: response1 network :"+response1.networkResponse());
response1.body().close();
} catch (IOException e) {
e.printStackTrace();
}
Call call12 = client.newCall(request);
try {
//第二次網(wǎng)絡(luò)請求
Response response2 = call12.execute();
Log.i(TAG, "testCache: response2 :"+response2.body().string());
Log.i(TAG, "testCache: response2 cache :"+response2.cacheResponse());
Log.i(TAG, "testCache: response2 network :"+response2.networkResponse());
Log.i(TAG, "testCache: response1 equals response2:"+response2.equals(response1));
response2.body().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
我們在上面的代碼中,用同一個url地址分別進行了兩次網(wǎng)絡(luò)訪問,然后分別用Log打印它們的信息。
10-24 21:17:04.720 9901-17925/? I/SeniorActivity: testCache: response1 :
\\ //
\\ .ooo. //
.@@@@@@@@@.
:@@@@@@@@@@@@@:
:@@. '@@@@@' .@@:
@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@
:@@ :@@@@@@@@@@@@@@@@@. @@:
@@@ '@@@@@@@@@@@@@@@@@, @@@
@@@ '@@@@@@@@@@@@@@@@@, @@@
@@@ '@@@@@@@@@@@@@@@@@, @@@
@@@ '@@@@@@@@@@@@@@@@@, @@@
@@@ '@@@@@@@@@@@@@@@@@, @@@
@@@ '@@@@@@@@@@@@@@@@@, @@@
@@@@@@@@@@@@@@@@@
'@@@@@@@@@@@@@@@'
@@@@ @@@@
@@@@ @@@@
@@@@ @@@@
'@@' '@@'
:@@@.
.@@@@@@@: +@@ `@@ @@` @@ @@
.@@@@'@@@@: +@@ `@@ @@` @@ @@
@@@ @@@ +@@ `@@ @@` @@ @@
.@@ @@: +@@ @@@ `@@ @@` @@@@@@ @@@@@@ @@;@@@@@
@@@ @@@ +@@ @@@ `@@ @@` @@@@@@ @@@@@@ @@@@@@@@@
@@@ @@@ +@@ @@@ `@@@@@@@@@@` @@ @@ @@@ :@@
@@@ @@@ +@@@@@ `@@@@@@@@@@` @@ @@ @@# @@+
@@@ @@@ +@@@@@+ `@@ @@` @@ @@ @@: @@#
@@: .@@` +@@@+@@ `@@ @@` @@ @@ @@# @@+
@@@. .@@@ +@@ @@@ `@@ @@` @@ @@ @@@ ,@@
@@@@@@@@@ +@@ @@@ `@@ @@` @@@@ @@@@ @@@@#@@@@
@@@@@@@ +@@ #@@ `@@ @@` @@@@: @@@@: @@'@@@@@
@@:
@@:
@@:
10-24 21:17:04.720 9901-17925/? I/SeniorActivity: testCache: response1 cache :null
10-24 21:17:04.720 9901-17925/? I/SeniorActivity: testCache: response1 network :Response{protocol=http/1.1, code=200, message=OK, url=https://publicobject.com/helloworld.txt}
10-24 21:17:05.031 9901-17925/? I/SeniorActivity: testCache: response2 :
\\ //
\\ .ooo. //
.@@@@@@@@@.
:@@@@@@@@@@@@@:
:@@. '@@@@@' .@@:
@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@
:@@ :@@@@@@@@@@@@@@@@@. @@:
@@@ '@@@@@@@@@@@@@@@@@, @@@
@@@ '@@@@@@@@@@@@@@@@@, @@@
@@@ '@@@@@@@@@@@@@@@@@, @@@
@@@ '@@@@@@@@@@@@@@@@@, @@@
@@@ '@@@@@@@@@@@@@@@@@, @@@
@@@ '@@@@@@@@@@@@@@@@@, @@@
@@@@@@@@@@@@@@@@@
'@@@@@@@@@@@@@@@'
@@@@ @@@@
@@@@ @@@@
@@@@ @@@@
'@@' '@@'
:@@@.
.@@@@@@@: +@@ `@@ @@` @@ @@
.@@@@'@@@@: +@@ `@@ @@` @@ @@
@@@ @@@ +@@ `@@ @@` @@ @@
.@@ @@: +@@ @@@ `@@ @@` @@@@@@ @@@@@@ @@;@@@@@
@@@ @@@ +@@ @@@ `@@ @@` @@@@@@ @@@@@@ @@@@@@@@@
@@@ @@@ +@@ @@@ `@@@@@@@@@@` @@ @@ @@@ :@@
@@@ @@@ +@@@@@ `@@@@@@@@@@` @@ @@ @@# @@+
@@@ @@@ +@@@@@+ `@@ @@` @@ @@ @@: @@#
@@: .@@` +@@@+@@ `@@ @@` @@ @@ @@# @@+
@@@. .@@@ +@@ @@@ `@@ @@` @@ @@ @@@ ,@@
@@@@@@@@@ +@@ @@@ `@@ @@` @@@@ @@@@ @@@@#@@@@
@@@@@@@ +@@ #@@ `@@ @@` @@@@: @@@@: @@'@@@@@
@@:
@@:
@@:
10-24 21:17:05.031 9901-17925/? I/SeniorActivity: testCache: response2 cache :Response{protocol=http/1.1, code=200, message=OK, url=https://publicobject.com/helloworld.txt}
10-24 21:17:05.031 9901-17925/? I/SeniorActivity: testCache: response2 network :null
10-24 21:17:05.031 9901-17925/? I/SeniorActivity: testCache: response1 equals response2:false
打印的結(jié)果非常有意思是一個機器人和一個Okhttp的字符串。打印的結(jié)果主要說明了一個現(xiàn)象,第一次訪問的時候,Response的消息是NetworkResponse消息,此時CacheResponse的值為Null.而第二次訪問的時候Response是CahceResponse,而此時NetworkResponse為空。也就說明了上面的示例代碼能夠進行網(wǎng)絡(luò)請求的緩存。
那么OKHTTP中的緩存就這么點內(nèi)容嗎?到此為至嗎?顯然不是。本篇文章開頭講了大段的Http協(xié)議中的相關(guān)知識點,貌似它們還沒有出現(xiàn)。
其實控制緩存的消息頭往往是服務(wù)端返回的信息中添加的如”Cache-Control:max-age=60”。所以,會有兩種情況。
- 客戶端和服務(wù)端開發(fā)能夠很好溝通,按照達成一致的協(xié)議,服務(wù)端按照規(guī)定添加緩存相關(guān)的消息頭。
- 客戶端與服務(wù)端的開發(fā)根本就不是同一家公司,沒有辦法也不可能要求服務(wù)端按照客戶端的意愿進行開發(fā)。
第一種辦法當(dāng)然很好,只要服務(wù)器在返回消息的時候添加好Cache-Control相關(guān)的消息便好。
第二種情況,就很麻煩,你真的無法左右別人的行為。怎么辦呢?好在OKHTTP能夠很輕易地處理這種情況。那就是定義一個攔截器,人為地添加Response中的消息頭,然后再傳遞給用戶,這樣用戶拿到的Response就有了我們理想當(dāng)中的消息頭Headers,從而達到控制緩存的意圖,正所謂移花接木。
緩存之?dāng)r截器
因為攔截器可以拿到Request和Response,所以可以輕而易舉地加工這些東西。在這里我們?nèi)藶榈靥砑覥ache-Control消息頭。
class CacheInterceptor implements Interceptor{
@Override
public Response intercept(Chain chain) throws IOException {
Response originResponse = chain.proceed(chain.request());
//設(shè)置緩存時間為60秒,并移除了pragma消息頭,移除它的原因是因為pragma也是控制緩存的一個消息頭屬性
return originResponse.newBuilder().removeHeader("pragma")
.header("Cache-Control","max-age=60").build();
}
}
定義好攔截器中后,我們可以添加到OKHttpClient中了。
private void testCacheInterceptor(){
//緩存文件夾
File cacheFile = new File(getExternalCacheDir().toString(),"cache");
//緩存大小為10M
int cacheSize = 10 * 1024 * 1024;
//創(chuàng)建緩存對象
final Cache cache = new Cache(cacheFile,cacheSize);
OkHttpClient client = new OkHttpClient.Builder()
.addNetworkInterceptor(new CacheInterceptor())
.cache(cache)
.build();
.......
}
代碼后面部分有省略。主要通過在OkHttpClient.Builder()中addNetworkInterceptor()中添加。而這樣也挺簡單的,就幾步完成了緩存代碼。
攔截器進行緩存的缺點
網(wǎng)上有人說用攔截器進行緩存是野路子,是HOOK行為。這個我不大同意,前面我有分析過情況,如果客戶端能夠同服務(wù)端一起協(xié)商開發(fā),當(dāng)然以服務(wù)器控制的緩存消息頭為準,但問題在于你沒法這樣做。所以,能夠解決問題才是最實在的。
好了,回到正題。用攔截器控制緩存有什么不好的地方呢?我們先看看下面的情況。
- 網(wǎng)絡(luò)訪問請求的資源是文本信息,如新聞列表,這類信息經(jīng)常變動,一天更新好幾次,它們用的緩存時間應(yīng)該就很短。
- 網(wǎng)絡(luò)訪問請求的資源是圖片或者視頻,它們變動很少,或者是長期不變動,那么它們用的緩存時間就應(yīng)該很長。
那么,問題來了。 因為OKHTTP開發(fā)建議是同一個APP,用同一個OKHTTPCLIENT對象這是為了只有一個緩存文件訪問入口。這個很容易理解,單例模式嘛。但是問題攔截器是在OKHttpClient.Builder當(dāng)中添加的。如果在攔截器中定義緩存的方法會導(dǎo)致圖片的緩存和新聞列表的緩存時間是一樣的,這顯然是不合理的,這屬于一刀切,就像這兩天專家說的要把年收入12萬元的人群劃分為高收入人群而不區(qū)別北上廣深的房價物價情況。真實的情況不應(yīng)該是圖片請求有它的緩存時間,新聞列表請求有它的緩存時間,應(yīng)該是每一個Request有它的緩存時間。 那么,有解決的方案嗎? 有的,okhttp官方有建議的方法。
okhttp官方文檔建議緩存方法
okhttp中建議用CacheControl這個類來進行緩存策略的制定。 它內(nèi)部有兩個很重要的靜態(tài)實例。
/**強制使用網(wǎng)絡(luò)請求*/
public static final CacheControl FORCE_NETWORK = new Builder().noCache().build();
/**
* 強制性使用本地緩存,如果本地緩存不滿足條件,則會返回code為504
*/
public static final CacheControl FORCE_CACHE = new Builder()
.onlyIfCached()
.maxStale(Integer.MAX_VALUE, TimeUnit.SECONDS)
.build();
我們看到FORCE_NETWORK常量用來強制使用網(wǎng)絡(luò)請求。FORCE_CACHE只取本地的緩存。它們本身都是CacheControl對象,由內(nèi)部的Buidler對象構(gòu)造。下面我們來看看CacheControl.Builder
CacheControl.Builder
它有如下方法:
- noCache();//不使用緩存,用網(wǎng)絡(luò)請求
- noStore();//不使用緩存,也不存儲緩存
- onlyIfCached();//只使用緩存
- noTransform();//禁止轉(zhuǎn)碼
- maxAge(10, TimeUnit.MILLISECONDS);//設(shè)置超時時間為10ms。
- maxStale(10, TimeUnit.SECONDS);//超時之外的超時時間為10s
- minFresh(10, TimeUnit.SECONDS);//超時時間為當(dāng)前時間加上10秒鐘
知道了CacheControl的相關(guān)信息,那么它怎么使用呢?不同于攔截器設(shè)置緩存,CacheControl是針對Request的,所以它可以針對每個請求設(shè)置不同的緩存策略。比如圖片和新聞列表。下面代碼展示如何用CacheControl設(shè)置一個60秒的超時時間。
private void testCacheControl(){
//緩存文件夾
File cacheFile = new File(getExternalCacheDir().toString(),"cache");
//緩存大小為10M
int cacheSize = 10 * 1024 * 1024;
//創(chuàng)建緩存對象
final Cache cache = new Cache(cacheFile,cacheSize);
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient client = new OkHttpClient.Builder()
.cache(cache)
.build();
//設(shè)置緩存時間為60秒
CacheControl cacheControl = new CacheControl.Builder()
.maxAge(60, TimeUnit.SECONDS)
.build();
Request request = new Request.Builder()
.url("http://blog.csdn.net/briblue")
.cacheControl(cacheControl)
.build();
try {
Response response = client.newCall(request).execute();
response.body().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
強制使用緩存
前面有講CacheControl.FORCE_CACHE這個常量。
public static final CacheControl FORCE_CACHE = new Builder()
.onlyIfCached()
.maxStale(Integer.MAX_VALUE, TimeUnit.SECONDS)
.build();
它內(nèi)部其實就是調(diào)用onlyIfCached()和maxStale方法。
它的使用方法為
Request request = new Request.Builder()
.url("http://blog.csdn.net/briblue")
.cacheControl(Cache.FORCE_CACHE)
.build();
但是如前面后提到的,如果緩存不符合條件會返回504.這個時候我們要根據(jù)情況再進行編碼,如緩存不行就再進行一次網(wǎng)絡(luò)請求。
Response forceCacheResponse = client.newCall(request).execute();
if (forceCacheResponse.code() != 504) {
// 資源已經(jīng)緩存了,可以直接使用
} else {
// 資源沒有緩存,或者是緩存不符合條件了。
}
不使用緩存
前面也有講CacheControl.FORCE_NETWORK這個常量。
public static final CacheControl FORCE_NETWORK = new Builder().noCache().build();
它的內(nèi)部其實是調(diào)用noCache()方法,也就是不緩存的意思。
它的使用方法為
Request request = new Request.Builder()
.url("http://blog.csdn.net/briblue")
.cacheControl(Cache.FORCE_NETWORK)
.build();
還有一種情況將maxAge設(shè)置為0,也不會取緩存,直接走網(wǎng)絡(luò)。
Request request = new Request.Builder()
.url("http://blog.csdn.net/briblue")
.cacheControl(new CacheControl.Builder()
.maxAge(0, TimeUnit.SECONDS))
.build();
總結(jié)
本文其實內(nèi)容不多,前面講了很多http協(xié)議下的緩存機制,我認為是值得的,知道了Cache-Control這些定義,才能更好的懂得OKHTTP中的緩存設(shè)置。能夠明白為什么它要這樣做,為什么它可以這樣做。 最后歸納下要點
http協(xié)議下Cache-Control等消息頭的作用
okhttp如何用攔截器添加Cache-Control消息頭進行緩存定制
okhttp如何用CacheControl進行緩存的控制。
轉(zhuǎn)載至:http://blog.csdn.net/briblue/article/details/52920531
Ref
http://www.cnblogs.com/l1pe1/archive/2010/07/14/1777621.html
http://www.cnblogs.com/whoislcj/p/5537640.html