1. 简介
OkHttp 是一个高效的 HTTP 客户端,广泛应用于 Android 和 Java 应用中。它支持同步和异步请求、连接池、透明压缩和缓存等特性。本文将深入分析 OkHttp 的源码,揭示其实现原理。
2. 项目结构
OkHttp 的项目结构大致如下:
okhttp/
│
├── okhttp/src/main/java/okhttp3/
│ ├── Cache.java
│ ├── Call.java
│ ├── Callback.java
│ ├── ConnectionPool.java
│ ├── Dispatcher.java
│ ├── Interceptor.java
│ ├── OkHttpClient.java
│ ├── Request.java
│ ├── Response.java
│ └── internal/
│ ├── cache/
│ ├── connection/
│ ├── http/
│ └── ws/
各个文件的功能如下:
Cache.java
:实现 HTTP 缓存。Call.java
:表示一次 HTTP 请求。Callback.java
:异步请求回调接口。ConnectionPool.java
:管理 HTTP 连接池。Dispatcher.java
:管理并发请求的调度。Interceptor.java
:拦截器机制。OkHttpClient.java
:OkHttp 的核心类,配置和执行 HTTP 请求。Request.java
:表示一个 HTTP 请求。Response.java
:表示一个 HTTP 响应。internal/
:内部实现类,包括缓存、连接和 HTTP 协议处理等。
3. 核心类分析
3.1 OkHttpClient 类
OkHttpClient
是 OkHttp 的核心类,用于配置和执行 HTTP 请求。
public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
final Dispatcher dispatcher;
final ConnectionPool connectionPool;
final List<Interceptor> interceptors;
final List<Interceptor> networkInterceptors;
final Cache cache;
// 其他字段省略
public OkHttpClient() {
this(new Builder());
}
private OkHttpClient(Builder builder) {
this.dispatcher = builder.dispatcher;
this.connectionPool = builder.connectionPool;
this.interceptors = Util.immutableList(builder.interceptors);
this.networkInterceptors = Util.immutableList(builder.networkInterceptors);
this.cache = builder.cache;
// 其他初始化代码省略
}
public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false);
}
public static final class Builder {
Dispatcher dispatcher;
ConnectionPool connectionPool;
List<Interceptor> interceptors = new ArrayList<>();
List<Interceptor> networkInterceptors = new ArrayList<>();
Cache cache;
// 其他字段省略
public Builder() {
this.dispatcher = new Dispatcher();
this.connectionPool = new ConnectionPool();
}
public OkHttpClient build() {
return new OkHttpClient(this);
}
}
}
OkHttpClient
类通过 Builder 模式进行配置和构建。newCall
方法创建一个新的 HTTP 请求。
3.2 Call 接口与 RealCall 类
Call
接口表示一次 HTTP 请求,RealCall
是其具体实现。
public interface Call extends Cloneable {
Request request();
Response execute() throws IOException;
void enqueue(Callback responseCallback);
void cancel();
boolean isExecuted();
boolean isCanceled();
Call clone();
}
final class RealCall implements Call {
private final OkHttpClient client;
private final Request originalRequest;
private boolean executed;
private RealCall(OkHttpClient client, Request originalRequest) {
this.client = client;
this.originalRequest = originalRequest;
}
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
RealCall call = new RealCall(client, originalRequest);
return call;
}
@Override
public Request request() {
return originalRequest;
}
@Override
public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
try {
client.dispatcher().executed(this);
Response result = getResponseWithInterceptorChain();
return result;
} finally {
client.dispatcher().finished(this);
}
}
@Override
public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
// 其他方法省略
Response getResponseWithInterceptorChain() throws IOException {
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(new RetryAndFollowUpInterceptor(client));
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, client.connectTimeoutMillis(), client.readTimeoutMillis(), client.writeTimeoutMillis());
return chain.proceed(originalRequest);
}
}
RealCall
实现了 Call
接口,通过 execute
方法同步执行请求,通过 enqueue
方法异步执行请求。getResponseWithInterceptorChain
方法构建了拦截器链并执行请求。
3.3 Dispatcher 类
Dispatcher
类负责管理并发请求的调度。
public final class Dispatcher {
private int maxRequests = 64;
private int maxRequestsPerHost = 5;
private final Deque<RealCall.AsyncCall> readyAsyncCalls = new ArrayDeque<>();
private final Deque<RealCall.AsyncCall> runningAsyncCalls = new ArrayDeque<>();
private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();
public synchronized void enqueue(RealCall.AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
public synchronized void executed(RealCall call) {
runningSyncCalls.add(call);
}
public synchronized void finished(RealCall.AsyncCall call) {
if (!runningAsyncCalls.remove(call)) throw new AssertionError("AsyncCall wasn't running!");
promoteCalls();
}
public synchronized void finished(RealCall call) {
if (!runningSyncCalls.remove(call)) throw new AssertionError("Call wasn't running!");
promoteCalls();
}
private void promoteCalls() {
if (runningAsyncCalls.size() >= maxRequests) return;
if (readyAsyncCalls.isEmpty()) return;
for (Iterator<RealCall.AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
RealCall.AsyncCall call = i.next();
if (runningCallsForHost(call) < maxRequestsPerHost) {
i.remove();
runningAsyncCalls.add(call);
executorService().execute(call);
}
if (runningAsyncCalls.size() >= maxRequests) return;
}
}
private int runningCallsForHost(RealCall.AsyncCall call) {
int result = 0;
for (RealCall.AsyncCall c : runningAsyncCalls) {
if (c.host().equals(call.host())) result++;
}
return result;
}
// 其他方法省略
}
Dispatcher
负责管理请求的并发执行,通过 enqueue
方法将异步请求加入队列,通过 promoteCalls
方法调度请求执行。
3.4 Interceptor 接口与 RealInterceptorChain 类
Interceptor
接口用于实现拦截器机制,RealInterceptorChain
类负责拦截器链的执行。
public interface Interceptor {
Response intercept(Chain chain) throws IOException;
interface Chain {
Request request();
Response proceed(Request request) throws IOException;
Connection connection();
}
}
public final class RealInterceptorChain implements Interceptor.Chain {
private final List<Interceptor> interceptors;
private final int index;
private final Request request;
private final Call call;
private final int connectTimeout;
private final int readTimeout;
private final int writeTimeout;
RealInterceptorChain(List<Interceptor> interceptors, Call call, Request request, int index, int connectTimeout, int readTimeout, int writeTimeout) {
this.interceptors = interceptors;
this.call = call;
this.request = request;
this.index = index;
this.connectTimeout = connectTimeout;
this.readTimeout = readTimeout;
this.writeTimeout = writeTimeout;
}
@Override
public Request request() {
return request;
}
@Override
public Response proceed(Request request) throws IOException {
if (index >= interceptors.size()) throw new AssertionError();
RealInterceptorChain next = new RealInterceptorChain(interceptors, call, request, index +