前言:
前面的學習基本上已經可以完成開發需求了,但是在項目中有時會遇到對請求做個緩存,當沒網絡的時候優先加載本地緩存,基於這個需求我們來學習一直okHttp的Cache-Control。
okHttp相關文章地址:
- Android okHttp網絡請求之Get/Post請求
- Android okHttp網絡請求之文件上傳下載
- Android okHttp網絡請求之Json解析
- Android okHttp網絡請求之緩存控制Cache-Control
- Android okHttp網絡請求之Retrofit+Okhttp組合
Cache-Control:
Cache-Control指定請求和響應遵循的緩存機制。在請求消息或響應消息中設置Cache-Control並不會修改另一個消息處理過程中的緩存處理過程。請求時的緩存指令有下幾種:
- Public指示響應可被任何緩存區緩存。
- Private指示對於單個用戶的整個或部分響應消息,不能被共享緩存處理。這允許服務器僅僅描述當用戶的部分響應消息,此響應消息對於其他用戶的請求無效。
- no-cache指示請求或響應消息不能緩存
- no-store用於防止重要的信息被無意的發布。在請求消息中發送將使得請求和響應消息都不使用緩存。
- max-age指示客戶機可以接收生存期不大於指定時間(以秒為單位)的響應。
- min-fresh指示客戶機可以接收響應時間小於當前時間加上指定時間的響應。
- max-stale指示客戶機可以接收超出超時期間的響應消息。如果指定max-stale消息的值,那么客戶機可以接收超出超時期指定值之內的響應消息。
CacheControl.java類介紹:
1.)常用的函數:如下代碼,里面已經加了注釋就不一一解釋了,每個函數都是對應一個緩存指令設置
final CacheControl.Builder builder = new CacheControl.Builder(); builder.noCache();//不使用緩存,全部走網絡 builder.noStore();//不使用緩存,也不存儲緩存 builder.onlyIfCached();//只使用緩存 builder.noTransform();//禁止轉碼 builder.maxAge(10, TimeUnit.MILLISECONDS);//指示客戶機可以接收生存期不大於指定時間的響應。 builder.maxStale(10, TimeUnit.SECONDS);//指示客戶機可以接收超出超時期間的響應消息 builder.minFresh(10, TimeUnit.SECONDS);//指示客戶機可以接收響應時間小於當前時間加上指定時間的響應。 CacheControl cache = builder.build();//cacheControl
2.)兩個CacheControl常量介紹:
CacheControl.FORCE_CACHE; //僅僅使用緩存 CacheControl.FORCE_NETWORK;// 僅僅使用網絡
舉例,我們設置一個有效期為10秒的CacheControl
final CacheControl.Builder builder = new CacheControl.Builder(); builder.maxAge(10, TimeUnit.MILLISECONDS); CacheControl cache = builder.build();
3.)請求時如何使用
final CacheControl.Builder builder = new CacheControl.Builder(); builder.maxAge(10, TimeUnit.MILLISECONDS); CacheControl cache = builder.build(); final Request request = new Request.Builder().cacheControl(cache).url(requestUrl).build(); final Call call = mOkHttpClient.newCall(request);// call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { failedCallBack("訪問失敗", callBack); Log.e(TAG, e.toString()); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { String string = response.body().string(); Log.e(TAG, "response ----->" + string); successCallBack((T) string, callBack); } else { failedCallBack("服務器錯誤", callBack); } } }); return call; } catch (Exception e) { Log.e(TAG, e.toString()); }
以上如果cache沒有過去會直接返回cache而不會發起網絡請求,若過期會自動發起網絡請求。注意:如果您使用FORCE_CACHE和網絡的響應需求,OkHttp則會返回一個504提示,告訴你不可滿足請求響應。所以我們加一個判斷在沒有網絡的情況下使用
//判斷網絡是否連接 boolean connected = NetworkUtil.isConnected(context); if (!connected) { request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build(); }
okHtitp知識擴展:
1.)Interceptor攔截器,見名知意就是攔截操作,這里用來攔截Request對其做一些特殊處理,舉例:比如上面我們使用到了CacheControl,我們怎么攔截一個請求在網絡不可用的時候使用CacheControl.FORCE_CACHE;
OkHttpClient.Builder newBuilder = mOkHttpClient.newBuilder(); newBuilder.addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); boolean connected = NetworkUtil.isConnected(context); if (!connected) { request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build(); } Response response = chain.proceed(request); return response; } });
2.)OkHttp 提供了對用戶認證的支持。當 HTTP 響應的狀態代碼是 401 時,OkHttp 會從設置的 Authenticator 對象中獲取到新的 Request 對象並再次嘗試發出請求。Authenticator 接口中的 authenticate 方法用來提供進行認證的 Request 對象.
OkHttpClient client = new OkHttpClient(); client.newBuilder().authenticator(new Authenticator() { @Override public Request authenticate(Route route, Response response) throws IOException { String credential = Credentials.basic("user", "password"); return response.request().newBuilder() .header("Authorization", credential) .build(); } });
小結:okHttp的簡單使用到此介紹完畢,至於很多高級使用還有待研究。接下來准備研究下OkHttp與retrofit結合使用。