OkHttp的緩存
看到很多小伙伴對(duì)OkHttp的緩存問(wèn)題并不是十分了解,于是打算來(lái)說(shuō)說(shuō)這個(gè)問(wèn)題。用好OkHttp中提供的緩存,可以幫助我們更好的使用Retrofit、Picasso等配合OkHttp使用的框架。OK,廢話不多說(shuō),我們來(lái)看看OkHttp中的緩存。
OkHttp中的緩存整體上來(lái)說(shuō)我們要在兩個(gè)地方配置,一個(gè)是構(gòu)造OkHttpClient時(shí),還有一個(gè)是在構(gòu)造Request時(shí),一共就這兩處,那我們分別來(lái)看看。
本文主要包含如下兩方面:
1.在OkHttpClient構(gòu)造時(shí)設(shè)置緩存路徑
2.構(gòu)造Request時(shí)配置緩存策略
OK,那就一步一步來(lái)看吧。
1.在OkHttpClient構(gòu)造時(shí)設(shè)置緩存路徑
我們?cè)谑褂肙kHttp的時(shí)候,一般都會(huì)將client的獲取封裝起來(lái),因?yàn)樵诖蠖鄶?shù)情況下,我們需要的OkHttpClient其實(shí)都是一樣的。在封裝的過(guò)程中,我們可以設(shè)置很多屬性,比如鏈接超時(shí)時(shí)間、讀取超時(shí)時(shí)間等,其中也包括我們即將要說(shuō)的cache,我們可以在這里來(lái)配置cache路徑,配置了cache路徑之后,OkHttp請(qǐng)求到的數(shù)據(jù)就會(huì)緩存到該路徑下,當(dāng)手機(jī)沒(méi)有聯(lián)網(wǎng)的時(shí)候,就可以直接從緩存中加載數(shù)據(jù)。我們來(lái)看看代碼:
OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(5, TimeUnit.SECONDS) .cache(new Cache(new File(this.getExternalCacheDir(), "okhttpcache"), 10 * 1024 * 1024)) .build();
我這里是設(shè)置了緩存的路徑為~/mnt/sdcard/Android/data/應(yīng)用包名/cache/okhttpcache,第二個(gè)參數(shù)表示緩存區(qū)的大小為10M,當(dāng)緩存區(qū)的數(shù)據(jù)大小超過(guò)10M的時(shí)候會(huì)自動(dòng)刪除已緩存的數(shù)據(jù),當(dāng)我們配置了緩存路徑之后,當(dāng)我發(fā)起一個(gè)網(wǎng)絡(luò) 請(qǐng)求之后,如下:
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(); } } } });
請(qǐng)求完畢之后,用一個(gè)TextView將請(qǐng)求結(jié)果顯示出來(lái),當(dāng)請(qǐng)求完畢之后,在我們上面所說(shuō)的那個(gè)目錄下,可以看到如下三個(gè)文件:
這里有三個(gè)文件,其中以.0結(jié)尾的文件緩存了http的響應(yīng)頭信息,以.1結(jié)尾的文件則緩存了我們下載的json數(shù)據(jù),journal則是一個(gè)日志文件,我們把這幾個(gè)文件打開(kāi)來(lái)看看:
.0
.1
journal
OK,配置了cache之后,當(dāng)我們請(qǐng)求過(guò)一次數(shù)據(jù)之后,然后關(guān)閉掉網(wǎng)絡(luò),這個(gè)時(shí)候再去請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù),這個(gè)時(shí)候OkHttp會(huì)自動(dòng)從本地緩存中重新加載數(shù)據(jù)。
2.構(gòu)造Request時(shí)配置緩存策略
上面的配置應(yīng)該已經(jīng)可以滿足許多小伙伴的需求了,可是很多時(shí)候我們還有許多其他的需求,那么這些需求我們可以在構(gòu)造Request的時(shí)候通過(guò)CacheControl來(lái)進(jìn)行進(jìn)一步的配置。
在構(gòu)造Request的時(shí)候,我們可以配置CacheControl,配置有兩種方式,一種是構(gòu)造CacheControl,還有一種是直接使用CacheControl中的常量,我們來(lái)分別看一下:
2.1構(gòu)造CacheControl
CacheControl cc = new CacheControl.Builder() //不使用緩存,但是會(huì)保存緩存數(shù)據(jù) //.noCache() //不使用緩存,同時(shí)也不保存緩存數(shù)據(jù) // .noStore() //只使用緩存,(如果我們要加載的數(shù)據(jù)本身就是本地?cái)?shù)據(jù)時(shí),可以使用這個(gè),不過(guò)目前尚未發(fā)現(xiàn)使用場(chǎng)景) //.onlyIfCached() //手機(jī)可以接收響應(yīng)時(shí)間小于當(dāng)前時(shí)間加上10s的響應(yīng) // .minFresh(10,TimeUnit.SECONDS) //手機(jī)可以接收有效期不大于10s的響應(yīng) // .maxAge(10,TimeUnit.SECONDS) //手機(jī)可以接收超出5s的響應(yīng) .maxStale(5,TimeUnit.SECONDS) .build(); Request request = new Request.Builder() .cacheControl(cc) .url("http://192.168.152.2:8080/cache").build();
這個(gè)用起來(lái)還是比較簡(jiǎn)單的,沒(méi)什么好說(shuō)的,重要代碼看注釋。
2.2使用CacheControl中的常量
如果直接使用CacheControl中的常量,則不用調(diào)用上面那么多的方法,使用方式如下:
Request request = new Request.Builder() //強(qiáng)制使用網(wǎng)絡(luò) // .cacheControl(CacheControl.FORCE_NETWORK) //強(qiáng)制使用緩存 .cacheControl(CacheControl.FORCE_CACHE) .url("http://192.168.152.2:8080/cache").build();
posted on 2018-05-20 10:51 安卓筆記俠 閱讀(636) 評(píng)論(0) 收藏 舉報(bào)
浙公網(wǎng)安備 33010602011771號(hào)