国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android OKHttp3攔截器的使用方法

2019-12-12 01:03:55
字體:
供稿:網(wǎng)友

本文介紹了Android OKHttp3攔截器的使用方法,分享給大家,具體如下:

添加Interceptor

在上一篇中我們已經(jīng)知道了okhttp的基本使用,其中在介紹OkHttpClient初始化的時(shí)候,介紹了兩種方式,第二種方式就可以對(duì)這個(gè)OkHttpClient對(duì)象設(shè)置攔截器,如下所示:

// 配置一些信息進(jìn)入OkHttpClientmOkHttpClient = new OkHttpClient().newBuilder()        .connectTimeout(REQUEST_TIME, TimeUnit.SECONDS)        .readTimeout(REQUEST_TIME, TimeUnit.SECONDS)        .writeTimeout(REQUEST_TIME, TimeUnit.SECONDS)        .addInterceptor(new LoggerInterceptor())        .build();

如上代碼,很簡單,只要利用addInterceptor方法就可以添加攔截器,而自定義的攔截器只需要實(shí)現(xiàn) Interceptor 接口就行了,如下所示:

public class LoggerInterceptor implements Interceptor {   ...}

應(yīng)用場景

日志打印

可以使用攔截器方便的打印網(wǎng)絡(luò)請(qǐng)求時(shí),需要查看的日志。如下所示:

public class LoggerInterceptor implements Interceptor {  @Override  public Response intercept(@NonNull Chain chain) throws IOException {    // 攔截請(qǐng)求,獲取到該次請(qǐng)求的request    Request request = chain.request();    // 執(zhí)行本次網(wǎng)絡(luò)請(qǐng)求操作,返回response信息    Response response = chain.proceed(request);    if (Configuration.DEBUG) {      for (String key : request.headers().toMultimap().keySet()) {        LogUtil.e("zp_test", "header: {" + key + " : " + request.headers().toMultimap().get(key) + "}");      }      LogUtil.e("zp_test", "url: " + request.url().uri().toString());      ResponseBody responseBody = response.body();      if (HttpHeaders.hasBody(response) && responseBody != null) {        BufferedReader bufferedReader = new BufferedReader(new            InputStreamReader(responseBody.byteStream(), "utf-8"));        String result;        while ((result = bufferedReader.readLine()) != null) {          LogUtil.e("zp_test", "response: " + result);        }        // 測試代碼        responseBody.string();      }    }    // 注意,這樣寫,等于重新創(chuàng)建Request,獲取新的Response,避免在執(zhí)行以上代碼時(shí),    // 調(diào)用了responseBody.string()而不能在返回體中再次調(diào)用。    return response.newBuilder().build();  }}

做了一個(gè)打印驗(yàn)證:通過分別打印攔截器與返回體的時(shí)間和線程名字,可以知道這兩者處于同一線程中,增加攔截器,請(qǐng)求執(zhí)行的時(shí)間也會(huì)增加,所以猜測,其實(shí)就是線性的在執(zhí)行不同攔截器中的代碼,根據(jù)需求返回一個(gè)相同的或者新的response。

緩存

想要實(shí)現(xiàn)緩存,先在創(chuàng)建okhttpclint的時(shí)候多加一行代碼 .cache() ,通過它來設(shè)置緩存目錄,當(dāng)然需要服務(wù)器支持緩存功能。

mOkHttpClient = new OkHttpClient().newBuilder()        .cache(new Cache(FileUtils.getCacheDirectory(AppApplication            .getApplication(), ""), 1024 * 1024))        .connectTimeout(REQUEST_TIME, TimeUnit.SECONDS)        .readTimeout(REQUEST_TIME, TimeUnit.SECONDS)        .writeTimeout(REQUEST_TIME, TimeUnit.SECONDS)        .addNetworkInterceptor(new LoggerInterceptor())        .build();

如果服務(wù)器端支持緩存的話,則請(qǐng)求所返回的Response會(huì)帶有這樣的頭信息header:cache-control, max-age=xxx,這樣設(shè)置。這時(shí)可以直接使用緩存功能。其中,max-age設(shè)置的緩存時(shí)間,過了這個(gè)時(shí)間,就算有緩存也不會(huì)進(jìn)行使用。

像我公司服務(wù)器返回的頭信息中與緩存相關(guān)的字段如下:

header: {cache-control : [no-store, private]}

header: {pragma : [no-cache]}

這就說明,服務(wù)器默認(rèn)是不支持緩存的,okhttp就不會(huì)對(duì)此次請(qǐng)求進(jìn)行緩存。

接下來再看攔截器中如何設(shè)置緩存

public class LoggerInterceptor implements Interceptor {  @Override  public Response intercept(@NonNull Chain chain) throws IOException {    // 攔截請(qǐng)求,獲取到該次請(qǐng)求的request    Request request = chain.request();    // 執(zhí)行本次網(wǎng)絡(luò)請(qǐng)求操作,返回response信息    Response response = chain.proceed(request);    if (Configuration.DEBUG) {      for (String key : request.headers().toMultimap().keySet()) {        LogUtil.e("zp_test", "header: {" + key + " : " + request.headers().toMultimap().get(key) + "}");      }      LogUtil.e("zp_test", "url: " + request.url().uri().toString());      ResponseBody responseBody = response.body();    }       return response.newBuilder()      // 增加一個(gè)緩存頭信息,緩存時(shí)間為60s      .header("cache-control", "public, max-age=60")       // 移除pragma頭信息      .removeHeader("pragma")      .build();  }}

這樣設(shè)置,就等于是在60s內(nèi)強(qiáng)制設(shè)置使用緩存。

注意點(diǎn):

切記,最開始,我一直在犯一個(gè)錯(cuò)誤,okhttp3不能緩存post接口

攔截器可以理解為,給請(qǐng)求的request和response重新一次封裝的機(jī)會(huì),使得你可以在特定條件下,給一些特定的接口或者滿足特定條件的接口一些特殊的操作。

比如有一種場景,有網(wǎng)絡(luò)時(shí),進(jìn)行請(qǐng)求,無網(wǎng)絡(luò)時(shí),拿緩存數(shù)據(jù)。

if (NetUtils.isNetAvailable(AppApplication.getApplication())) {    response.newBuilder()         .header("Cache-Control", "public, max-age=" + 0)         .removeHeader("Pragma")         .build();  } else {    int maxStale = 60 * 60 * 24; // 無網(wǎng)絡(luò)時(shí),設(shè)置超時(shí)為1天   response.newBuilder()        .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)        .removeHeader("Pragma")        .build();  } return response;

max-stale:在max-age指定的失效時(shí)間外,額外增加一段指定的時(shí)間可以使用失效的response。

網(wǎng)上有很多是上面這種做法,但是,我在攔截器中試了一下,當(dāng)沒有網(wǎng)絡(luò)時(shí),壓根就不會(huì)走入攔截器。(我使用的是網(wǎng)絡(luò)攔截器,如果有是別的什么原因,歡迎指出錯(cuò)誤)

最終解決方案是在初始化request(如果初始化不熟悉可以參考我的上一篇文章OKHttp3的基本使用)的時(shí)候進(jìn)行的判斷操作,當(dāng)有網(wǎng)絡(luò)時(shí)初始化正常的request,當(dāng)沒有網(wǎng)絡(luò)時(shí)初始化強(qiáng)制使用緩存的request:

Request request;if (NetUtils.isNetAvailable(AppApplication.getApplication())) {   request = addHeaderInfo().url(requestUrl).build();} else {   request = addHeaderInfo().url(requestUrl).cacheControl(CacheControl.FORCE_CACHE).build();}

攔截器還是使用上面的那種形式,只是將有效時(shí)間變成了0

response.newBuilder()        .header("Cache-Control", "public, max-age=" + 0)        .removeHeader("Pragma")        .build();

這樣就可以在有網(wǎng)絡(luò)的情況下使用最新的數(shù)據(jù),在無網(wǎng)絡(luò)的情況下使用緩存數(shù)據(jù)。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 建平县| 双桥区| 赫章县| 辽阳县| 二连浩特市| 冕宁县| 汾西县| 十堰市| 兰州市| 易门县| 紫阳县| 宜宾市| 竹北市| 雅安市| 辽源市| 龙陵县| 沿河| 安远县| 新平| 清远市| 呼图壁县| 陆良县| 泸州市| 弥勒县| 大竹县| 阳江市| 山丹县| 咸阳市| 荃湾区| 巩留县| 襄汾县| 延川县| 莱芜市| 江山市| 荆门市| 宾川县| 饶阳县| 瑞安市| 大冶市| 富阳市| 连城县|