1. 程式人生 > >OKHTTP中快取使用理解

OKHTTP中快取使用理解

一、快取使用的背景 APP在網路請求過程中,存在這樣幾個場景,在斷網情況下需要APP頁面存在原有網路請求下來的圖片和資訊;不論網路是否正常,某些後臺資訊在短時間內都不會被更新了,APP中觸發的網路請求不用去後臺獲取資訊,給後臺帶來壓力;使用者的資訊必須去後臺進行更新,獲取最新的資訊,比如使用者的資金方面的資訊。這三類場景就涉及到了Http中的網路請求中的快取,只有瞭解了Http快取知識點才能知道對上述三類場景如何進行應對。二、HTTP 快取引數說明 HTTP快取可以分為兩類,一類是在request中新增引數,是用來告知伺服器;一類是在response中新增引數,用來通知客戶端;在設定快取時需要Get的requset或response的header中新增Cache-Control:引數。引數的定義有如下:
public:(僅為響應標頭)         reponse:告知任何途徑的快取者,可以無條件的快取該響應。private:(僅為響應標頭)         response:告知快取者, 只針對單個使用者快取響應。且可以具體指定某個欄位如private –“username”,則響應頭中,名為username的標頭內容,不會被共享快取。no-cache: requset:告知快取者,必須原原本本的轉發原始請求,並告知任何快取者,別直接拿你快取的副本糊弄人。你需要去轉發我的請求,並驗證你的快取(如果有的話)。對應名詞:端對端過載.        response:允許快取者快取副本。那麼其實際價值是,總是強制快取者校驗快取的新鮮度。在確認快取新鮮的情況下,可以使用快取副本作為響應。no-cache還可以指定某個包含欄位,比如一個典型應用,no-cache=Set-Cookie. 這樣做的結果,就是告知快取者,對於Set-Cookie欄位,你不要使用快取內容.而是使用新滴.其他內容則可以使用快取.
max-age:       request:強制響應快取者,根據該值校驗新鮮性,即自身的Age值與請求時間做比較。如果超出max-age值,則強制去伺服器端驗證,以確保返回一個新鮮的響應。在當max-age=0時,代表強制伺服器返回最新的結果。其功能本質上與傳統的Expires類似。但區別在於Expires是根據某個特定日期值做比較,一但快取者自身的時間不準確,則結果可能就是錯誤的。而max-age,顯然無此問題。Max-age的優先順序也是高於Expires的。            reponse:指示客戶機可以接收生存期不大於指定時間(以秒為單位)的響應。三、在OKHTTP中使用快取
OKHTTP在建立的時候可在攔截機中新增快取配置,參考程式碼如下:
OkHttpClient.Builder builder = new OkHttpClient.Builder();builder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);builder.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);builder.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);if (Ln.isDebugEnabled()) { HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC); builder.interceptors().add(loggingInterceptor);}builder.cache(new Cache(new File(context.getFilesDir(), "responses"), CONST_10 * CONST_1024 * CONST_1024)); //設定快取存在路徑和大小if (DevSettingStore.isDevChannel()) { builder.interceptors().add(new DevUrlInterceptor(context));}builder.interceptors().add(new NetStatisticsInterceptor());// 無網路時,快取一天builder.interceptors().add(new LocalCacheInterceptor(context, NetAccessStrategy.DEFAULT_MAX_LOCAL_CACHE_SECONDS));// 有網路時,快取時間設定builder.networkInterceptors().add(0, new NetCacheInterceptor(NetAccessStrategy.DEFAULT_MAX_NET_CACHE_SECONDS));builder.build();
LocalCacheInterceptor的程式碼定義如下,在request請求中如果沒定義快取“Cache-Control”欄位的情況下,如果網路環境不可以上網,則在網路請求中設定使用快取的時效,讓http請求不用去伺服器請求資料,直接使用快取中的資料就可以了。
package common.retrofit.interceptor;import android.content.Context;import android.text.TextUtils;import common.retrofit.NetAccessStrategy;import common.utils.NetworkUtils;import java.io.IOException;import java.util.concurrent.TimeUnit;import okhttp3.CacheControl;import okhttp3.Interceptor;import okhttp3.Request;import okhttp3.Response;public class LocalCacheInterceptor implements Interceptor {private int maxCacheSeconds;private Context context;public LocalCacheInterceptor(Context context, int maxCacheSeconds) {this.context = context;this.maxCacheSeconds = maxCacheSeconds; }@Overridepublic Response intercept(Chain chain) throws IOException { Request request = chain.request(); String header = request.header("Cache-Control");if (TextUtils.isEmpty(header)) {if (!NetworkUtils.isNetworkAvailable(context)) { Request.Builder builder = request.newBuilder();//if network not available, load in cacheCacheControl cacheControl = new CacheControl.Builder().maxAge(Integer.MAX_VALUE, TimeUnit.SECONDS) .maxStale(maxCacheSeconds, TimeUnit.SECONDS).build(); request = builder.cacheControl(cacheControl).build(); return chain.proceed(request); } } else if (NetAccessStrategy.NO_CONTROL.equals(header)) { Request.Builder builder = request.newBuilder();if (NetworkUtils.isNetworkAvailable(context)) { builder.removeHeader("Cache-Control"); } else {//if network not available, load in cacheCacheControl cacheControl = new CacheControl.Builder().maxAge(Integer.MAX_VALUE, TimeUnit.SECONDS) .maxStale(maxCacheSeconds, TimeUnit.SECONDS).build(); builder.cacheControl(cacheControl); }return chain.proceed(builder.build()); } else if (header.startsWith(NetAccessStrategy.NET_REQUEST)) { Request.Builder builder = request.newBuilder();int[] timeArray = NetAccessStrategy.getRequestCacheTime(header); CacheControl cacheControl = new CacheControl.Builder().maxAge(timeArray[0], TimeUnit.SECONDS).build(); NetAccessStrategy.setThreadLocalCacheTime(timeArray[1]); builder.cacheControl(cacheControl);return chain.proceed(builder.build()); }return chain.proceed(request); }}
NetCacheInterceptor的定義如下,承接上面 LocalCacheInterceptor中的邏輯,設定不同的reponse快取時間。
package common.retrofit.interceptor;import android.text.TextUtils;import common.retrofit.NetAccessStrategy;import java.io.IOException;import okhttp3.Interceptor;import okhttp3.Request;import okhttp3.Response;public class NetCacheInterceptor implements Interceptor {private int maxCacheSeconds;public NetCacheInterceptor(int maxCacheSeconds) {this.maxCacheSeconds = maxCacheSeconds; }@Overridepublic Response intercept(Chain chain) throws IOException { Request request = chain.request();int time = NetAccessStrategy.getThreadLocalCacheTime();if (TextUtils.isEmpty(request.header("Cache-Control"))) { Request.Builder builder = request.newBuilder(); request = builder.build(); Response originalResponse = chain.proceed(request);return originalResponse.newBuilder().header("Cache-Control", "public, max-age=" + maxCacheSeconds) .build(); } else { Request.Builder builder = request.newBuilder(); request = builder.build(); Response originalResponse = chain.proceed(request);if (time > 0) {return originalResponse.newBuilder().header("Cache-Control", "public, max-age=" + time) .build(); }return originalResponse.newBuilder().header("Cache-Control", request.header("Cache-Control")) .build(); } }}
快取邏輯屬於之前同事寫的邏輯,針對快取的邏輯編寫有點繞,個人的理解是:在有網的環境下會對所有網路請求進行一次快取,快取的時間限制為max-age的值,在沒有網路的情況下,強制去快取中去,取的同時更新延長response快取中的時間,另外根據快取的時間值控制不能快取的場景,比如個人資訊。參考連結

相關推薦

OKHTTP快取使用理解

一、快取使用的背景 APP在網路請求過程中,存在這樣幾個場景,在斷網情況下需要APP頁面存在原有網路請求下來的圖片和資訊;不論網路是否正常,某些後臺資訊在短時間內都不會被更新了,APP中觸發的網路請求不用去後臺獲取資訊,給後臺帶來壓力;使用者的資訊必須去後臺進行

ios--->OCProtocol理解及在代理模式的使用

markdown 全部 interface int n) 遇到 其它 car mailto OC中Protocol理解及在代理模式中的使用 Protocol基本概念 Protocol翻譯過來, 叫做”協議”,其作用就是用來聲明一些方法; Protocol(協議)的作用

scalaStream理解

求值 nbsp pan stream int cal scala 全部 head // Stream:Stream is lazy List; // Stream惰性求值指它只確定第一個值,後面的值用到再求值,這樣可以防止數據過大全部加載導致內存溢出 // 將

tensorflow reduce_sum 理解

post flow const body 理解 ant pan ims tensor 定義如下: reduce_sum( input_tensor, axis=None, keep_dims=False, name=None,

(轉)Python如何理解if __name__ == '__main__'

面向 知識 about main 想要 二進制 imp space 包導入 摘要 通俗的理解 __name__ == ‘__main__‘ :假如你叫李凱.py,在朋友眼中,你是李凱( __name__ == ‘李凱‘ );在你自己眼中,你是你自己( __name__ ==

package.json版本理解

bsp 滿足 ack pac one isp .json style Bugfix 一個完整的版本號可以理解為: [主要版本號,次要版本號,補丁版本號]版本號 x.y.z :其中z 表示一些小的bugfix, y表示一些大的版本更改,比如一些API的變化x表示一些設計的變動

如何找到微信快取的檔案以及微信網頁下載的遊戲

第一級目錄為 : Tencent   第二級目錄為:MicroMsg (微信)  MobileQQ  (QQ)   第三級目錄為:BigFile (儲存大的檔案 如遊戲)   檔名是隨機加密的 我們可以從大小看出 

03 -1 pandas DataFrame理解與建立、索引、運算的詳解以及例項

DataFrame DataFrame是一個【表格型】的資料結構,可以看做是【由Series組成的字典】(共用同一個索引)。DataFrame由按一定順序排列的多列資料組成。設計初衷是將Series的使用場景從一維拓展到多維。DataFrame既有行索引,也有列索引。 行索引

Hibernate Session一級快取理解

Hibernate框架中有2級快取: 1.其中一級快取主要為Session快取,透過session查詢到資料庫的內容會被存到session快取中    後續如果訪問就不會從資料庫拿資料,而是直接從session快取中(也就是記憶體)取資料。減少了資料庫訪問次數。 &n

web前端部署過程快取出現的問題 生產實戰經驗 移動端H5

目錄 增加時間戳 或者 版本號 chrome: provisional header are showed 漏掉的ng-include 手機各種機型 對快取的不同處理 (2018) – 移動端H5混合應用的新版本生產部署之後, 出現的各種情況和實

Retrofit+okhttp+rxjava, 快取策略使用

主要涉及幾個要點:  要使用離線快取的頁面網路請求方式必須要用GET(POST不可以),其他不要的頁面還是用POST 在新增攔截器時,需要新增網路攔截器( .addNetworkInterceptor(new NetInterceptor()) //有網情況下,一分鐘內每次

vue專案快取問題

單頁面應用總是存在快取問題,特別是在微信端,更新頁面之後訪問的還是老頁面,快取的問題是因為使用者訪問的指令碼地址並沒有改變,瀏覽器就會讀取原來的指令碼 網上有幾種解決辦法,首先列舉一下 1.加meta,禁止頁面快取 如果有些功能需要頁面快取的話這種方式就不適用,而且禁止快取之後使用者的請求的次數就會

H5快取機制

webstorage機制 一、localStorage 用於永久性的進行本地快取,不會自動清除、沒有過期時間,直至手動清除資料。 儲存方式 ● 以鍵值對的形式進行儲存 , 儲存的方式只能是String型別。獲取的資料也只能是String型別 window.localStorage.setIte

redis 第 13 篇 工作記錄-在專案快取是如何使用的?快取如果使用不當會造成什麼後果?

    針對每一個技術,必須具備深入的瞭解,這個技術的更新活躍度,使用這個技術的優點,使用這個技術的缺點,不使用的缺點以及優點。如果不這樣的話,智只能說明自己平時思考的太少了,只知道幹活。 (1)為啥要使用快取 用快取,主要是倆用途,高效能和高併發 高效能

python快取模組的一些用法

python快取模組的一些用法 一.問題描述 有時候可能需要快取一些 成員方法的值, 可能成員方法的計算比較耗時,有時候不希望重複呼叫計算該值, 這個時候就可以快取該值. 查了一下標準庫 有 functools.lru_cache 有一個 lru_cac

C#快取的使用

快取的概念及優缺點在這裡就不多做介紹,主要介紹一下使用的方法。 1.在ASP.NET中頁面快取的使用方法簡單,只需要在aspx頁的頂部加上一句宣告即可:    <%@ OutputCache Duration="100" VaryByParam="none" %>    Duration:快取時間

web開發快取機制的種類

1.資料庫快取 我們可能聽說過memcached,它就是一種資料庫層面的快取方案。資料庫快取是指,當web應用的關係比較複雜,資料庫中的表很多的時候,如果頻繁進行 資料庫查詢,很容易導致資料庫不堪重荷。為了提供查詢的效能,將查詢後的資料放到記憶體中進行快取,下次

HDU 2087 剪花布條 KMP(判斷不重疊區間加以判斷)在看題逐漸理解kmp...

http://acm.hdu.edu.cn/showproblem.php?pid=2087 #include <iostream> #include<cstdio> #include<algorithm> #include<cstring> #i

百度地圖開發理解的部分(二)

不是很明白allowBackup的方法 查詢一下 Android API Level 8及其以上Android系統提供了為應用程式資料的備份和恢復功能,此功能的開關決定於該應用程式中AndroidManifest.xml檔案中的allowBackup屬性值

Python fork()理解

參考:多程序- 廖雪峰的官方網站 首先,在python中我們要實現多程序,有兩個模組可以用: 1)os中的fork()函式 2)multiprocessing模組 那麼這兩個模組有什麼區別呢? 在for