一,概述
在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);
}
注意點:
- 方法的返回值是Response 。這個就是網絡請求的目的,得到的數據都封裝在Response 對象中。
- 攔截器的使用。在方法的第一行中就創建了interceptors 集合,然後緊接着放進去很多攔截器對象。
- 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;
}
分析:
- 注意index和calls兩個整形字段,如果index大於等於集合的長度,calls就++,calls大於1就會拋出異常。所以在正常情況下index是小於集合的長度的。
- index的初始化在RealInterceptorChain的構造方法中,也就是在getResponseWithInterceptorChain放中創建RealInterceptorChain對象時被初始化的。我們發現初始化值是0。
- 在該方法末尾再次創建RealInterceptorChain對象,此時index值是1。然後得到攔截器對象,調用攔截器的intercept方法,並把index等於1的RealInterceptorChain對象傳遞過去。
- interceptor的intercept方法的返回值是Response 。注意Response 是從這兒來的。