上回書說到OkHttp的基本使用,其實平時也不單獨使用OkHttp來做網絡請求,都是搭配Retrofit來請求網絡數據。Retrofit+okhttp基本使用下一章在說,今天寫一下OkHttp的源碼分析以及工作流程。
先上圖(有圖才能發現真相):
OkHttp請求流程圖
從流程圖中可以看出,無論是同步請求還是異步請求,最終都是交給RealCall#getResponseWithInterceptorChain()執行網絡請求操作。
RealCall#getResponseWithInterceptorChain()實現如下:
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 (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
originalRequest, this, eventListener, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
return chain.proceed(originalRequest);
}
在getResponseWithInterceptorChain OkHttp創建了一個列表對象之後把 client 中的攔截器、重連攔截器(RetryAndFollowUpInterceptor)、橋攔截器(BridgeInterceptor)、緩存攔截器(CacheInterceptor)、網絡連接攔截器(ConnectInterceptor)和服務器請求攔截器(CallServerInterceptor)等依次加入到列表中。然後,我們用這個列表創建了一個Interceptor.Chain(攔截器鏈)。這裏使用了責任鏈設計模式,每當一個攔截器執行完畢之後會調用下一個攔截器或者不調用並返回結果。顯然,我們最終拿到的響應就是這個鏈條執行之後返回的結果。當我們自定義一個攔截器的時候,也會被加入到這個攔截器鏈條裏。
在getResponseWithInterceptorChain各個攔截器的功能如下:
- 在配置 OkHttpClient 時設置的 interceptors(如一些自定義的攔截器);
- 負責請求失敗時重試以及重定向的 RetryAndFollowUpInterceptor;
- 負責把用戶構造的請求轉換爲發送到服務器的請求、把服務器返回的響應轉換爲用戶友好的響應的 BridgeInterceptor;
- 負責讀取緩存直接返回、更新緩存的 CacheInterceptor;
- 負責和服務器建立連接的 ConnectInterceptor;
- 配置 OkHttpClient 時設置的 networkInterceptors;
- 負責向服務器發送請求數據、從服務器讀取響應數據的 CallServerInterceptor。
Interceptor(攔截器)
OkHttp的作者之一這樣形容它:
the whole thing is just a stack of built-in interceptors.
所以攔截器是OkHttp最核心的東西,也是廣大面試官必問的點。
Interceptor其實不是說只是用來負責一些額外的操作處理(比如 緩存、異常攔截處理等),它在OkHttp中實際上是把網絡請求流程中的:網絡請求、緩存、異常處理等功能都統一起來,每一個功能就是一個Interceptor,然後所有的Interceptor連接在一起形成一個 Interceptor.Chain,最終圓滿完成一次網絡請求。