攔截器的作用在APP開發中是相當重要的,這篇文章分析一下Okhttp中是怎麼實現一條攔截器鏈,希望能幫助大家更好去了解攔截器的作用
幾個關鍵類以及介面
-
RealInterceptorChain
-
Interceptor
RealInterceptorChain
RealInterceptorChain
實現了Interceptor
介面,呼叫源頭來自於RealCall
的getResponseWithInterceptorChain
方法
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
/**
* 1
*/
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));
/**
* 2
*/
Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);
}
複製程式碼
1. 第一處是把自定義的攔截器先加入進去,然後把okhttp內建的一些攔截器按照功能順序add進list裡
2. 第二處是整個攔截器工作的源頭,先new了一個RealInterceptorChain
,index為0,把初始的request
傳了進去,然後呼叫proceed
獲取請求的response
接下來看一下proceed方法的具體實現,忽略掉一些檢查
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
RealConnection connection) throws IOException {
if (index >= interceptors.size()) throw new AssertionError();
calls++;
/**
* 1
*/
// Call the next interceptor in the chain.
RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,
connection, index + 1, request, call, eventListener, connectTimeout, readTimeout,
writeTimeout);
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);
return response;
}
複製程式碼
先是檢查一下index是否超出interceptors
也就是攔截器list的長度,接著又new了一個RealInterceptorChain
,把當前RealInterceptorChain
的一些引數屬性都傳了進去,並且在這裡把index + 1
,這個地方很重要,在這裡可以把RealInterceptorChain
想象成把攔截器給包裝了起來,然後用下一個攔截器生成一個新的RealInterceptorChain
中,然後把index+1
下標的chain
傳進了當前攔截器的intercept
方法裡,也就是我們自定義攔截器的時候需要重寫的intercept
方法,也就是說我們新增的攔截器裡的intercept
方法中RealInterceptorChain
物件,實際上裡面包含有整個request
以及下一個攔截器。所以就形成了一條鏈,每一個攔截器都持有下一個攔截器經過包裝之後的RealInterceptorChain
物件,直到攔截器鏈的最後一個攔截器CallServerInterceptor
這個攔截器會做最後的處理,然後開始請求生成Response
並且返回。攔截器可以通過intercept
方法獲取下一個攔截器return
的response
,而且會通過proceed
方法向下一個攔截器傳遞自己處理過的Requeset
到這裡總結一下各個方法以及類的作用
-
RealInterceptorChain
包裝了攔截器以及網路請求的資訊
-
RealInterceptorChain.proceed
引數中有
Request
,是上一個攔截器包裝過後的Request
,然後將下一個攔截器和整個Request
的資訊包裝成RealInterceptorChain
,並且會呼叫當前攔截器的intercept
方法把下一個攔截器(RealInterceptorChain
)傳進去,並且獲取到Response
-
Interceptor.intercept
方法引數是下一個
Chain
也就是RealInterceptorChain
,然後呼叫RealInterceptorChain.request()
去獲取請求,呼叫RealInterceptorChain.proceed()
去獲取Response