一網打盡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();

OK,這個就是我們OkHttp中緩存的一個基本使用,有問題歡迎留言討論。


以上。




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM