看到很多小伙伴對OkHttp的緩存問題並不是十分瞭解,於是打算來說說這個問題。用好OkHttp中提供的緩存,可以幫助我們更好的使用Retrofit、Picasso等配合OkHttp使用的框架。OK,廢話不多說,我們來看看OkHttp中的緩存。 OkHttp中的緩存整體上來說我們要在兩個地方配置,一個 ...
看到很多小伙伴對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();