最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android OKHttp3攔截器的使用方法

 更新時間:2018年03月29日 10:15:57   作者:軒雅而為  
本篇文章主要介紹了Android OKHttp3攔截器的使用方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

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

添加Interceptor

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

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

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

public class LoggerInterceptor implements Interceptor {
   ...
}

應用場景

日志打印

可以使用攔截器方便的打印網絡請求時,需要查看的日志。如下所示:

public class LoggerInterceptor implements Interceptor {

  @Override
  public Response intercept(@NonNull Chain chain) throws IOException {
    // 攔截請求,獲取到該次請求的request
    Request request = chain.request();
    // 執(zhí)行本次網絡請求操作,返回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í)行以上代碼時,
    // 調用了responseBody.string()而不能在返回體中再次調用。
    return response.newBuilder().build();
  }

}

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

緩存

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

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();

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

像我公司服務器返回的頭信息中與緩存相關的字段如下:

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

header: {pragma : [no-cache]}

這就說明,服務器默認是不支持緩存的,okhttp就不會對此次請求進行緩存。

接下來再看攔截器中如何設置緩存

public class LoggerInterceptor implements Interceptor {

  @Override
  public Response intercept(@NonNull Chain chain) throws IOException {
    // 攔截請求,獲取到該次請求的request
    Request request = chain.request();
    // 執(zhí)行本次網絡請求操作,返回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()
      // 增加一個緩存頭信息,緩存時間為60s
      .header("cache-control", "public, max-age=60")
       // 移除pragma頭信息
      .removeHeader("pragma")
      .build();
  }
}

這樣設置,就等于是在60s內強制設置使用緩存。

注意點:

切記,最開始,我一直在犯一個錯誤,okhttp3不能緩存post接口

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

比如有一種場景,有網絡時,進行請求,無網絡時,拿緩存數(shù)據。

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

return response;

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

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

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

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

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

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

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Android中PathMeasure仿支付寶支付動畫

    Android中PathMeasure仿支付寶支付動畫

    這篇文章主要為大家詳細介紹了Android中PathMeasure仿支付寶支付動畫,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Android使用popUpWindow帶遮罩層的彈出框

    Android使用popUpWindow帶遮罩層的彈出框

    這篇文章主要為大家詳細介紹了Android使用popUpWindow帶遮罩層的彈出框,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • 獲取Activity棧,判斷當前Activity位置的方法

    獲取Activity棧,判斷當前Activity位置的方法

    下面小編就為大家分享一篇獲取Activity棧,判斷當前Activity位置的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • Kotlin全局捕捉協(xié)程異常方法詳解

    Kotlin全局捕捉協(xié)程異常方法詳解

    協(xié)程是互相協(xié)作的程序,協(xié)程是結構化的。如果把Java的異常處理機制,照搬到Kotlin協(xié)程中,一定會遇到很多的坑。Kotlin協(xié)程中的異常主要分兩大類,協(xié)程取消異常(CancellationException) 其他異常
    2022-08-08
  • Android Activity與Fragment之間的跳轉實例詳解

    Android Activity與Fragment之間的跳轉實例詳解

    這篇文章主要介紹了Android Activity與Fragment之間的跳轉實例詳解的相關資料,需要的朋友可以參考下
    2017-02-02
  • Kotlin?lambda表達式入門指南

    Kotlin?lambda表達式入門指南

    在kotlin當中,Lambda表達式是最高等級的,Lambda表達式可以理解為一種匿名函數(shù),是一種高效的類似于函數(shù)式編程的表達式,本文介紹Kotlin?lambda表達式入門指南,感興趣的朋友一起看看吧
    2024-03-03
  • 深入了解Android Okio的超時機制

    深入了解Android Okio的超時機制

    Okio是一個IO庫,底層基于Java原生的輸入輸出流實現(xiàn)。但原生的輸入輸出流并沒有提供超時的檢測機制。而Okio實現(xiàn)了這個功能,本文就來為大家詳細講講
    2023-02-02
  • Android中檢查、監(jiān)聽電量和充電狀態(tài)的方法

    Android中檢查、監(jiān)聽電量和充電狀態(tài)的方法

    這篇文章主要介紹了Android中檢查、監(jiān)聽電量和充電狀態(tài)的方法,如判斷當前充電狀態(tài)、監(jiān)聽充電狀態(tài)的改變、判斷當前剩余電量等,需要的朋友可以參考下
    2014-06-06
  • Android實現(xiàn)類似360,QQ管家那樣的懸浮窗

    Android實現(xiàn)類似360,QQ管家那樣的懸浮窗

    用到的就是WindowManager以及WindowManager.LayoutParams,對這個LayoutParams做文章,當設置為屬性后,然后,創(chuàng)建一個View,將這個View添加到WindowManager中就行
    2013-06-06
  • 如何設置Android studio 3.0顯示光標返回上一次瀏覽位置的箭頭圖標

    如何設置Android studio 3.0顯示光標返回上一次瀏覽位置的箭頭圖標

    這篇文章主要介紹了如何設置Android studio 3.0顯示光標返回上一次瀏覽位置的箭頭圖標 很多朋友反映剛升級了Android studio 3.0,發(fā)現(xiàn)光標返回上一次瀏覽位置的箭頭圖標沒有了,下文給大家介紹的非常詳細,需要的朋友可以參考下
    2017-11-11

最新評論

汉沽区| 乌恰县| 平阴县| 集安市| 涪陵区| 建德市| 墨竹工卡县| 五峰| 五寨县| 东辽县| 太仆寺旗| 上高县| 怀集县| 株洲市| 六安市| 五常市| 乾安县| 石嘴山市| 靖西县| 昌邑市| 石首市| 拜泉县| 墨江| 深水埗区| 西贡区| 津市市| 伊宁市| 罗田县| 平罗县| 浠水县| 巴青县| 平潭县| 宁夏| 耿马| 高邮市| 怀仁县| 云安县| 贵南县| 马边| 长岭县| 铜川市|