看到很多小伙伴對OkHttp的緩存問題並不是十分了解,於是打算來說說這個問題。用好OkHttp中提供的緩存,可以幫助我們更好的使用Retrofit、Picasso等配合OkHttp使用的框架。OK,廢話不多說,我們來看看OkHttp中的緩存。
OkHttp中的緩存整體上來說我們要在兩個地方配置,一個是構造OkHttpClient時,還有一個是在構造Request時,一共就這兩處,那我們分別來看看。
本文主要包含如下兩方面:
1.在OkHttpClient構造時設置緩存路徑
2.構造Request時配置緩存策略
OK,那就一步一步來看吧。
1.在OkHttpClient構造時設置緩存路徑
我們在使用OkHttp的時候,一般都會將client的獲取封裝起來,因為在大多數情況下,我們需要的OkHttpClient其實都是一樣的。在封裝的過程中,我們可以設置很多屬性,比如鏈接超時時間、讀取超時時間等,其中也包括我們即將要說的cache,我們可以在這里來配置cache路徑,配置了cache路徑之后,OkHttp請求到的數據就會緩存到該路徑下,當手機沒有聯網的時候,就可以直接從緩存中加載數據。我們來看看代碼:
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(5, TimeUnit.SECONDS)
.cache(new Cache(new File(this.getExternalCacheDir(), "okhttpcache"), 10 * 1024 * 1024))
.build();
我這里是設置了緩存的路徑為 ~/mnt/sdcard/Android/data/應用包名/cache/okhttpcache,第二個參數表示緩存區的大小為10M,當緩存區的數據大小超過10M的時候會自動刪除已緩存的數據,當我們配置了緩存路徑之后,當我發起一個網絡 請求之后,如下:
Request request = new Request.Builder().url("http://www.tngou.net/api/food/list?id=1").build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
sb = new StringBuffer();
try {
JSONObject jo = new JSONObject(response.body().string());
JSONArray tngou = jo.optJSONArray("tngou");
for (int i = 0; i < tngou.length(); i++) {
sb.append(tngou.optJSONObject(i).optString("name")).append("\n");
}
runOnUiThread(new Runnable() {
@Override
public void run() {
tv.setText(sb.toString());
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
請求完畢之后,用一個TextView將請求結果顯示出來,當請求完畢之后,在我們上面所說的那個目錄下,可以看到如下三個文件:

這里有三個文件,其中以.0結尾的文件緩存了http的響應頭信息,以.1結尾的文件則緩存了我們下載的json數據,journal則是一個日志文件,我們把這幾個文件打開來看看:
.0

.1

journal

OK,配置了cache之后,當我們請求過一次數據之后,然后關閉掉網絡,這個時候再去請求網絡數據,這個時候OkHttp會自動從本地緩存中重新加載數據。
2.構造Request時配置緩存策略
上面的配置應該已經可以滿足許多小伙伴的需求了,可是很多時候我們還有許多其他的需求,那么這些需求我們可以在構造Request的時候通過CacheControl來進行進一步的配置。
在構造Request的時候,我們可以配置CacheControl,配置有兩種方式,一種是構造CacheControl,還有一種是直接使用CacheControl中的常量,我們來分別看一下:
2.1構造CacheControl
CacheControl cc = new CacheControl.Builder()
//不使用緩存,但是會保存緩存數據
//.noCache()
//不使用緩存,同時也不保存緩存數據
// .noStore()
//只使用緩存,(如果我們要加載的數據本身就是本地數據時,可以使用這個,不過目前尚未發現使用場景)
//.onlyIfCached()
//手機可以接收響應時間小於當前時間加上10s的響應
// .minFresh(10,TimeUnit.SECONDS)
//手機可以接收有效期不大於10s的響應
// .maxAge(10,TimeUnit.SECONDS)
//手機可以接收超出5s的響應
.maxStale(5,TimeUnit.SECONDS)
.build();
Request request = new Request.Builder()
.cacheControl(cc)
.url("http://192.168.152.2:8080/cache").build();
這個用起來還是比較簡單的,沒什么好說的,重要代碼看注釋。
2.2使用CacheControl中的常量
如果直接使用CacheControl中的常量,則不用調用上面那么多的方法,使用方式如下:
Request request = new Request.Builder()
//強制使用網絡
// .cacheControl(CacheControl.FORCE_NETWORK)
//強制使用緩存
.cacheControl(CacheControl.FORCE_CACHE)
.url("http://192.168.152.2:8080/cache").build();
OK,這個就是我們OkHttp中緩存的一個基本使用,有問題歡迎留言討論。
以上。
