Android的HTTP擴(kuò)展包OkHttp中的緩存功能使用方法解析
OkHttp 可以對 HTTP 響應(yīng)的內(nèi)容在磁盤上進(jìn)行緩存。在進(jìn)行 HTTP 請求時,如果該請求的響應(yīng)已經(jīng)被緩存而且沒有過期,OkHttp 會直接使用緩存中的響應(yīng)內(nèi)容,而不需要真正的發(fā)出 HTTP 請求到遠(yuǎn)程服務(wù)器。在創(chuàng)建緩存時需要指定一個磁盤目錄和緩存的大小。在代碼清單 8 中,創(chuàng)建出 Cache 對象之后,通過 OkHttpClient 的 setCache 進(jìn)行設(shè)置。通過 Response 對象的 cacheResponse 和 networkResponse 方法可以得到緩存的響應(yīng)和從實(shí)際的 HTTP 請求得到的響應(yīng)。如果該請求的響應(yīng)來自實(shí)際的網(wǎng)絡(luò)請求,則 cacheResponse 方法的返回值為 null;如果響應(yīng)來自緩存,則 networkResponse 的返回值為 null。OkHttp 在進(jìn)行緩存時會遵循 HTTP 協(xié)議的要求,因此可以通過標(biāo)準(zhǔn)的 HTTP 頭 Cache-Control 來控制響應(yīng)的緩存時間。
設(shè)置響應(yīng)緩存的示例
public class CacheResponse { public static void main(String[] args) throws IOException { int cacheSize = 100 * 1024 * 1024; File cacheDirectory = Files.createTempDirectory("cache").toFile(); Cache cache = new Cache(cacheDirectory, cacheSize); OkHttpClient client = new OkHttpClient(); client.setCache(cache); Request request = new Request.Builder() .url("http://www.baidu.com") .build(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) { throw new IOException("服務(wù)器端錯誤: " + response); } System.out.println(response.cacheResponse()); System.out.println(response.networkResponse()); } }
Cache-Control
Cache-Control指定請求和響應(yīng)遵循的緩存機(jī)制。在請求消息或響應(yīng)消息中設(shè)置Cache-Control并不會修改另一個消息處理過程中的緩存處理過程。請求時的緩存指令有下幾種:
Public指示響應(yīng)可被任何緩存區(qū)緩存。
Private指示對于單個用戶的整個或部分響應(yīng)消息,不能被共享緩存處理。這允許服務(wù)器僅僅描述當(dāng)用戶的部分響應(yīng)消息,此響應(yīng)消息對于其他用戶的請求無效。
(1)no-cache指示請求或響應(yīng)消息不能緩存
(2)no-store用于防止重要的信息被無意的發(fā)布。在請求消息中發(fā)送將使得請求和響應(yīng)消息都不使用緩存。
(3)max-age指示客戶機(jī)可以接收生存期不大于指定時間(以秒為單位)的響應(yīng)。
(4)min-fresh指示客戶機(jī)可以接收響應(yīng)時間小于當(dāng)前時間加上指定時間的響應(yīng)。
(5)max-stale指示客戶機(jī)可以接收超出超時期間的響應(yīng)消息。如果指定max-stale消息的值,那么客戶機(jī)可以接收超出超時期指定值之內(nèi)的響應(yīng)消息。
CacheControl類詳細(xì)介紹:
1.)常用的函數(shù):如下代碼,里面已經(jīng)加了注釋就不一一解釋了,每個函數(shù)都是對應(yīng)一個緩存指令設(shè)置
final CacheControl.Builder builder = new CacheControl.Builder(); builder.noCache();//不使用緩存,全部走網(wǎng)絡(luò) builder.noStore();//不使用緩存,也不存儲緩存 builder.onlyIfCached();//只使用緩存 builder.noTransform();//禁止轉(zhuǎn)碼 builder.maxAge(10, TimeUnit.MILLISECONDS);//指示客戶機(jī)可以接收生存期不大于指定時間的響應(yīng)。 builder.maxStale(10, TimeUnit.SECONDS);//指示客戶機(jī)可以接收超出超時期間的響應(yīng)消息 builder.minFresh(10, TimeUnit.SECONDS);//指示客戶機(jī)可以接收響應(yīng)時間小于當(dāng)前時間加上指定時間的響應(yīng)。 CacheControl cache = builder.build();//cacheControl
2.)兩個CacheControl常量介紹:
CacheControl.FORCE_CACHE; //僅僅使用緩存 CacheControl.FORCE_NETWORK;// 僅僅使用網(wǎng)絡(luò)
舉例,我們設(shè)置一個有效期為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("服務(wù)器錯誤", callBack); } } }); return call; } catch (Exception e) { Log.e(TAG, e.toString()); }
以上如果cache沒有過去會直接返回cache而不會發(fā)起網(wǎng)絡(luò)請求,若過期會自動發(fā)起網(wǎng)絡(luò)請求。注意:如果您使用FORCE_CACHE和網(wǎng)絡(luò)的響應(yīng)需求,OkHttp則會返回一個504提示,告訴你不可滿足請求響應(yīng)。所以我們加一個判斷在沒有網(wǎng)絡(luò)的情況下使用
//判斷網(wǎng)絡(luò)是否連接 boolean connected = NetworkUtil.isConnected(context); if (!connected) { request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build(); }
相關(guān)文章
Flutter使用texture_rgba_renderer實(shí)現(xiàn)桌面端渲染視頻詳解
這篇文章主要為大家介紹了Flutter如何使用texture_rgba_renderer實(shí)現(xiàn)桌面端渲染視頻,文中的示例代碼講解詳細(xì),需要的可以了解一下2023-07-07Android實(shí)現(xiàn)獲取聯(lián)系人電話號碼功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)獲取聯(lián)系人電話號碼功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-03-03Android實(shí)現(xiàn)五子棋游戲(局域網(wǎng)版)
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)局域網(wǎng)版的五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05Android如何實(shí)現(xiàn)設(shè)備的異顯功能詳解
這篇文章主要給大家介紹了關(guān)于Android如何實(shí)現(xiàn)設(shè)備的異顯功能的相關(guān)資料,這篇文章通過示例代碼介紹的非常詳細(xì),對各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2022-02-02在不同Activity之間傳遞數(shù)據(jù)的四種常用方法
這篇文章主要介紹了在不同Activity之間傳遞數(shù)據(jù)的四種常用方法 的相關(guān)資料,需要的朋友可以參考下2016-03-03Android拖拽助手ViewDragHelper的創(chuàng)建與使用實(shí)例
ViewDragHelper是針對 ViewGroup 中的拖拽和重新定位 views 操作時提供了一系列非常有用的方法和狀態(tài)追蹤,下面這篇文章主要給大家介紹了關(guān)于Android拖拽助手ViewDragHelper的創(chuàng)建與使用的相關(guān)資料,需要的朋友可以參考下2022-05-05