天天看點

Android之OkHttp源碼分析一關鍵類介紹1.OkHttp關鍵類和類的作用2.攔截的調用順序

目錄

1.OkHttp關鍵類和類的作用

1.1.OkHttpClient(請求用戶端)

1.2.Request

1.3.RealCall

1.4執行請求相關類

1.5.Dispatcher

1.7.BridgeInterceptor

1.8.CacheInterceptor

1.9.ConnectInterceptor

1.10.CallServerInterceptor

2.攔截的調用順序

1.OkHttp關鍵類和類的作用

1.1.OkHttpClient(請求用戶端)

OkHttpClient是用于生産Call {@linkplain Call calls}的工廠,可以發送請求和讀取請求傳回的響應資訊;

a.OkHttpClients應該被公用的

當我們建立一個{@code OkHttpClient}執行個體時并且複用它為了所有的HTTP請求調用時将是更高效的。這是因為彼此用戶端都擁有自己的連接配接池和線程池。複用連接配接和線程将減少延遲并節省記憶體。相反,為每一個請求都建立用戶端将是浪費資源。使用{@code new OkHttpClient()}建立一個有預設配置公用的執行個體,代碼如下;

{@code

    // The singleton HTTP client.

    public final OkHttpClient client = new OkHttpClient();

}

或者使用 {@code new OkHttpClient.Builder()}去建立一個有定制配置的公用的執行個體,代碼如下;

{@code

    // The singleton HTTP client.

    public final OkHttpClient client = new OkHttpClient.Builder()

        .addInterceptor(new HttpLoggingInterceptor())

        .cache(new Cache(cacheDir, cacheSize))

        .build();

}

b.使用newBuilder()定制你的用戶端

你能使用{@link #newBuilder()}定制一個共享的OkHttpClient的執行個體。這個将建立一個共享相同連接配接池,線程池和配置的用戶端。使用builder方法去配置為了特殊用途的派生用戶端。這個展示一個500毫秒逾時的調用例子:

{@code

    OkHttpClient eagerClient = client.newBuilder()//判斷出來的用戶端-共享連接配接池,線程池等

        .readTimeout(500, TimeUnit.MILLISECONDS)

        .build();

    Response response = eagerClient.newCall(request).execute();

  }

c.關閉連接配接或者線程池不是必須的

如果它們保持空閑的,線程和連接配接将被自動釋放。但是,如果您正在編寫一個需要積極釋放未使用的資源的應用程式,您可以這樣做。

關閉dispatcher的線程池服務使用{@link ExecutorService#shutdown shutdown()}。這也會導緻将來客戶被拒絕的調用。

{@code

      client.dispatcher().executorService().shutdown();

 }

d.使用{@link ConnectionPool#evictAll() evictAll()}清理連接配接池。注意,那個連接配接池的背景線程不能立即退出。

{@code

      client.connectionPool().evictAll();

 }

e.如果你的用戶端有一個緩存,調用 {@link Cache#close close()}。注意去建立一個被關閉的緩存的調用将是錯誤的,并且這樣将引起崩潰。

{@code

     client.cache().close();

}

f.OkHttp為了HTTP/2連接配接也使用背景線程。如果它們空閑,這些連接配接将自動退出

1.2.Request

包裝的一個HTTP請求,如果body是null或者它自己不可變,類的執行個體也是不可變的;

//包含請求的如下資訊
  private final HttpUrl url;//請求的url
  private final String method;//請求的方法
  private final Headers headers;//請求頭
  private final RequestBody body;//請求的body
  private final Object tag;//請求的标記
           

1.3.RealCall

RealCall是一個封裝已經準備去執行的請求的調用。這個調用可以被取消。作為這個對象表示單個請求/響應對(流),不能執行兩次。

1.4執行請求相關類

調用RealCall的execute()執行請求時,檢視下面RealCall類中請求的方法如下:

@Override public Response execute() throws IOException {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    try {
      client.dispatcher().executed(this);
      Response result = getResponseWithInterceptorChain();
      if (result == null) throw new IOException("Canceled");
      return result;
    } finally {
      client.dispatcher().finished(this);
    }
  }
           

我們會看到具體執行網絡請求關鍵步驟類的部分,主要有Dispatcher類和RealCall類下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);
  }
           

RetryAndFollowUpInterceptor,BridgeInterceptor,CacheInterceptor,ConnectInterceptor,CallServerInterceptor。

1.5.Dispatcher

每個Dispatcher使用一個{@ Link ExecutorService }在内部運作調用。如果你提供你的自己的executor,它應該能夠運作 {@linkplain #getMaxRequests 配置的最大}數量的并發調用。

1.6.RetryAndFollowUpInterceptor

這個攔截器可以從請求失敗和重定向中按需要恢複。 它可能抛出異常 {@link IOException} 如何調用被取消。

1.7.BridgeInterceptor

從應用程式代碼到網絡代碼的橋梁。首先,它從使用者請求建立網絡請求,然後繼續調用網絡請求。最後,根據網絡響應建立使用者響應。

1.8.CacheInterceptor

服務緩存中的請求并向緩存寫入響應。

1.9.ConnectInterceptor

打開到目标伺服器的連接配接,并執行下一個攔截器。

1.10.CallServerInterceptor

這是最後一個攔截器,它将調用一個到伺服器的網絡請求。

2.攔截的調用順序

Android之OkHttp源碼分析一關鍵類介紹1.OkHttp關鍵類和類的作用2.攔截的調用順序

繼續閱讀