OKHttp原碼分析(四)之getResponseWithInterceptorChain方法

一,概述

OKHttp原碼分析(一)最後講到無論是同步請求還是異步請求都殊途同歸到了RealCall的getResponseWithInterceptorChain方法。這篇blog主要講解RealCall的getResponseWithInterceptorChain方法。

二,getResponseWithInterceptorChain方法源碼

  private Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());
    interceptors.add(retryAndFollowUpInterceptor);
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    interceptors.add(new CacheInterceptor(client.internalCache()));
    interceptors.add(new ConnectInterceptor(client));
    if (!retryAndFollowUpInterceptor.isForWebSocket()) {
      interceptors.addAll(client.networkInterceptors());
    }
    interceptors.add(new CallServerInterceptor(
        retryAndFollowUpInterceptor.isForWebSocket()));

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

注意點:

  1. 方法的返回值是Response 。這個就是網絡請求的目的,得到的數據都封裝在Response 對象中。
  2. 攔截器的使用。在方法的第一行中就創建了interceptors 集合,然後緊接着放進去很多攔截器對象。
  3. RealInterceptorChain類的proceed方法。getResponseWithInterceptorChain方法的最後創建了RealInterceptorChain對象,並調用proceed方法。Response 對象就有由RealInterceptorChain類的proceed方法返回的。

下面看RealInterceptorChain類的proceed方法的原碼。

三,RealInterceptorChain類的proceed方法的原碼

  public Response proceed(Request request, StreamAllocation streamAllocation, HttpStream httpStream,Connection connection) throws IOException {
    if (index >= interceptors.size()) throw new AssertionError();
    calls++;
    // If we already have a stream, confirm that this is the only call to chain.proceed().
    if (this.httpStream != null && calls > 1) {
      throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
          + " must call proceed() exactly once");
    }

    // Call the next interceptor in the chain.
    RealInterceptorChain next = new RealInterceptorChain(
        interceptors, streamAllocation, httpStream, connection, index + 1, request);
    Interceptor interceptor = interceptors.get(index);
    Response response = interceptor.intercept(next);
    return response;
  }

分析:

  1. 注意index和calls兩個整形字段,如果index大於等於集合的長度,calls就++,calls大於1就會拋出異常。所以在正常情況下index是小於集合的長度的。
  2. index的初始化在RealInterceptorChain的構造方法中,也就是在getResponseWithInterceptorChain放中創建RealInterceptorChain對象時被初始化的。我們發現初始化值是0。
  3. 在該方法末尾再次創建RealInterceptorChain對象,此時index值是1。然後得到攔截器對象,調用攔截器的intercept方法,並把index等於1的RealInterceptorChain對象傳遞過去。
  4. interceptor的intercept方法的返回值是Response 。注意Response 是從這兒來的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章