(一)Interceptor chain
OkHttp 的 Interceptor chain 是比較特色的一個(gè)東西齐鲤。我們通過添加自定義的 Interceptor 可以對(duì)請(qǐng)求的前斥废、后做一些額外的攔截處理,然而實(shí)際上 OkHttp 框架的核心流程也是通過它實(shí)現(xiàn)的给郊,以下是 RealCall 中的 getResponseWithInterceptorChain() 方法:
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
// 用戶自定義的 interceptor
interceptors.addAll(client.interceptors());
// 負(fù)責(zé)失敗重試以及重定向的
interceptors.add(retryAndFollowUpInterceptor);
/** Bridges from application code to network code.
* First it builds a network request from a user request.
* Then it proceeds to call the network.
* Finally it builds a user response from the network response. */
interceptors.add(new BridgeInterceptor(client.cookieJar()));
/** Serves requests from the cache and writes responses to the cache. */
interceptors.add(new CacheInterceptor(client.internalCache()));
/** Opens a connection to the target server and proceeds to the next interceptor. */
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
/** This is the last interceptor in the chain. It makes a network call to the server. */
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);
}
Interceptor chain 是個(gè) 責(zé)任鏈模式
它包含了一些命令對(duì)象和一系列的處理對(duì)象牡肉,每一個(gè)處理對(duì)象決定它能處理哪些命令對(duì)象,它也知道如何將它不能處理的命令對(duì)象傳遞給該鏈中的下一個(gè)處理對(duì)象淆九。該模式還描述了往該處理鏈的末尾添加新的處理對(duì)象的方法统锤。
Interceptor 便是這樣,它首先實(shí)現(xiàn)自己的職責(zé)炭庙,比如 BridgeInterceptor 首先通過客戶端的 request 創(chuàng)建一個(gè) Request.Builder饲窿,然后調(diào)用下一個(gè) Interceptor(也就是 CacheInterceptor,可以參考下圖中 Interceptor 的調(diào)用順序) 的 proceed 來得到 response煤搜,
Response networkResponse = chain.proceed(requestBuilder.build());
最后構(gòu)建一個(gè)新的 Response.Builder 并返回免绿。
其實(shí) Interceptor 的設(shè)計(jì)也是一種分層的思想,每個(gè) Interceptor 就是一層擦盾,分層簡(jiǎn)化了每一層的邏輯嘲驾,每層只需要關(guān)注自己的責(zé)任(單一原則思想也在此體現(xiàn))淌哟,而各層之間通過約定的接口/協(xié)議進(jìn)行合作(面向接口編程思想),共同完成復(fù)雜的任務(wù)辽故。
(二)自定義 Interceptor
- 比如請(qǐng)求中添加統(tǒng)一的 header 和 QueryParameter徒仓;
- 沒有網(wǎng)絡(luò)的情況下,嘗試使用 cache誊垢。
……
private static class RequestInterceptor implements Interceptor {
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
Request.Builder requestBuilder = chain.request().newBuilder();
requestBuilder.addHeader("os_name", "Android");
……
return chain.proceed(requestBuilder.build());
}
}