okhttp中interceptors和networkInterceptors的区别

在学习okhttp时发现在OkHttpClient内部有两个用来存储interceptor的链表,分别是interceptors和networkInterceptors,那么这两个列表中存储的interceptor有什么区别呢?

1
2
3
4
public class OkHttpClien{
final List<Interceptor> interceptors;
final List<Interceptor> networkInterceptors;
}

要想弄清楚这个问题,我们首先要知道Interceptor是什么并且okhttp的网络请求处理流程是怎样的。

Interceptor简介

Interceptor是一个接口,类图如下所示
标准模板

java 文档中对其的介绍是:

Observes, modifies, and potentially short-circuits requests going out and the corresponding responses coming back in. Typically interceptors add, remove, or transform headers on the request or response.

就是说Interceptor观察,修改并且可能短路发送的请求和相应的服务端返回的内容。一些特殊的Interceptor会添加,删除或者转换网络请求和响应的头部。

okhttp网络请求处理流程

okhttp网络请求的核心代码如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
final class RealCall implements Call {
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);
}
}
public final class RealInterceptorChain implements Interceptor.Chain {
private final List<Interceptor> interceptors;
private final int index;
public Response proceed(Request request, StreamAllocation
// 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;
}
}

我们看到,最后调用了RealInterceptorChain的procced方法来处理我们的请求。RealInterceptorChain类内部维护了一个index,用来记录传进来的request应该由哪个Interceptor来处理。在Interceptor的intercept方法中只要通过调用chain.process就可将请求传递给下一个Interceptor来处理。这种模式是一个典型的责任链模式。

总结

由于interceptors和networkInterces在责任链中的位置不同,他们能做的事情也就不同了。比如,如果我们要对服务端返回的数据做自定义缓存就应该在interceptors中处理,而如果我们想控制网络请求的创建连接等就应该在networkInterceptor中处理了