OkHttp源码解析

OkHttp源码解析

拦截器:
  • RetryAndFollowUpInterceptor : 重试以及重定向拦截器
  • BridgeInterceptor : 用户请求与服务器响应桥接拦截器
  • CacheInterceptor : 缓存拦截器
  • ConnectInterceptor : 服务器连接拦截器
  • CallServerInterceptor : 读取服务响应拦截器
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
public interface Interceptor {
Response intercept(Chain chain) throws IOException;

interface Chain {
Request request();

Response proceed(Request request) throws IOException;

/**
* Returns the connection the request will be executed on.
* This is only available in the chains of network interceptors;
* for application interceptors this is always null.
*/
@Nullable Connection connection();

Call call();

int connectTimeoutMillis();

Chain withConnectTimeout(int timeout, TimeUnit unit);

int readTimeoutMillis();

Chain withReadTimeout(int timeout, TimeUnit unit);

int writeTimeoutMillis();

Chain withWriteTimeout(int timeout, TimeUnit unit);
}
}

RealInterceptorChain:

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public final class RealInterceptorChain implements Interceptor.Chain {
...
public Response proceed(Request request,
StreamAllocation streamAllocation,
HttpCodec httpCodec,
RealConnection connection) throws IOException {
if (index >= interceptors.size()) throw new AssertionError();

calls++;

// If we already have a stream, confirm that the incoming request will use it.
if (this.httpCodec != null &&
!this.connection.supportsUrl(request.url())) {
throw new IllegalStateException("network interceptor " +
interceptors.get(index - 1) +
" must retain the same host and port");
}

// If we already have a stream, confirm that this is the only call to chain.proceed().
if (this.httpCodec != 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, httpCodec,
connection, index + 1, request, call,
eventListener, connectTimeout, readTimeout,
writeTimeout);
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);

// Confirm that the next interceptor made its required call to chain.proceed().
if (httpCodec != null &&
index + 1 < interceptors.size() && next.calls != 1) {
throw new IllegalStateException("network interceptor " +
interceptor +
" must call proceed() exactly once");
}

// Confirm that the intercepted response isn't null.
if (response == null) {
throw new NullPointerException("interceptor " +
interceptor +
" returned null");
}

if (response.body() == null) {
throw new IllegalStateException("interceptor " +
interceptor +
" returned a response with no body");
}

return response;
}
}
Dispatcher:
3条请求队列:

readyAsyncCalls(异步准备队列)
runningAsyncCalls(异步执行队列)
runningSyncCalls(同步执行队列)

Call:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public interface Call extends Cloneable {

Request request();

Response execute() throws IOException;

void enqueue(Callback responseCallback);

void cancel();

boolean isExecuted();

boolean isCanceled();

Call clone();

interface Factory {
Call newCall(Request request);
}
}
  • RealCall:
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
 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);
}
...
}