OkHttp 拾遺

(一)Interceptor chain

OkHttp 的 Interceptor chain 是比較特色的一個東西。我們通過添加自定義的 Interceptor 可以對請求的前、后做一些額外的攔截處理,然而實際上 OkHttp 框架的核心流程也是通過它實現的,以下是 RealCall 中的 getResponseWithInterceptorChain() 方法:

Response getResponseWithInterceptorChain() throws IOException {
  // Build a full stack of interceptors.
  List<Interceptor> interceptors = new ArrayList<>();

  // 用戶自定義的 interceptor
  interceptors.addAll(client.interceptors());

  // 負責失敗重試以及重定向的
  interceptors.add(retryAndFollowUpInterceptor);

  /** Bridges from application code to network code.
     * First it builds a network request from a user request. 
     * Then it proceeds to call the network. 
     * Finally it builds a user response from the network response. */
  interceptors.add(new BridgeInterceptor(client.cookieJar()));

  /** Serves requests from the cache and writes responses to the cache. */
  interceptors.add(new CacheInterceptor(client.internalCache()));

  /** Opens a connection to the target server and proceeds to the next interceptor. */
  interceptors.add(new ConnectInterceptor(client));

  if (!forWebSocket) {
    interceptors.addAll(client.networkInterceptors());
  }

  /** This is the last interceptor in the chain. It makes a network call to the server. */
  interceptors.add(new CallServerInterceptor(forWebSocket));

  Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0, originalRequest);
  return chain.proceed(originalRequest);
}

Interceptor chain 是個 責任鏈模式

它包含了一些命令對象和一系列的處理對象,每一個處理對象決定它能處理哪些命令對象,它也知道如何將它不能處理的命令對象傳遞給該鏈中的下一個處理對象。該模式還描述了往該處理鏈的末尾添加新的處理對象的方法。

Interceptor 便是這樣,它首先實現自己的職責,比如 BridgeInterceptor 首先通過客戶端的 request 創建一個 Request.Builder,然后調用下一個 Interceptor(也就是 CacheInterceptor,可以參考下圖中 Interceptor 的調用順序) 的 proceed 來得到 response,

Response networkResponse = chain.proceed(requestBuilder.build());

最后構建一個新的 Response.Builder 并返回。

OkHttp 流程圖

其實 Interceptor 的設計也是一種分層的思想,每個 Interceptor 就是一層,分層簡化了每一層的邏輯,每層只需要關注自己的責任(單一原則思想也在此體現),而各層之間通過約定的接口/協議進行合作(面向接口編程思想),共同完成復雜的任務。

(二)自定義 Interceptor
  1. 比如請求中添加統一的 header 和 QueryParameter;
  2. 沒有網絡的情況下,嘗試使用 cache。
    ……
private static class RequestInterceptor implements Interceptor {
        @Override
        public Response intercept(@NonNull Chain chain) throws IOException {
                Request.Builder requestBuilder = chain.request().newBuilder();
                requestBuilder.addHeader("os_name", "Android");
                ……
                return chain.proceed(requestBuilder.build());
        }
  }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,993評論 19 139
  • 關于okhttp是一款優秀的網絡請求框架,關于它的源碼分析文章有很多,這里分享我在學習過程中讀到的感覺比較好的文章...
    蕉下孤客閱讀 3,625評論 2 38
  • 安卓開發領域,很多重要的問題都有了很好的開源解決方案,例如網絡請求 OkHttp + Retrofit 簡直就是不...
    我是濤鍋鍋閱讀 507評論 0 0
  • 用OkHttp很久了,也看了很多人寫的源碼分析,在這里結合自己的感悟,記錄一下對OkHttp源碼理解的幾點心得。 ...
    藍灰_q閱讀 4,380評論 4 34
  • 美容養顏抗衰老 是個永恒的話題 所有的女性都關心這個話題。 市面上有無數的美瞳化妝品, 但要找到一個既能美容又不損...
    藍蝶_8263閱讀 421評論 0 0