一、整体思路
从使用方法出发,首先是怎么使用,其次是我们使用的功能在内部是如何实现的,实现方案上有什么技巧,有什么范式。全文基本上是对 OkHttp 源码的一个分析与导读,非常建议大家下载 OkHttp 源码之后,跟着本文,过一遍源码。对于技巧和范式,由于目前我的功力还不到位,分析内容没多少,欢迎大家和我一起讨论。
首先放一张完整流程图(看不懂没关系,慢慢往后看):
二、基本用例
来自OkHttp 官方网站。
2.1.创建 OkHttpClient 对象
OkHttpClient client = new OkHttpClient();
咦,怎么不见 builder?莫急,且看其构造函数:
public OkHttpClient() {
this(new Builder());
}
原来是方便我们使用,提供了一个“快捷操作”,全部使用了默认的配置。OkHttpClient.Builder
类成员很多,后面我们再慢慢分析,这里先暂时略过:
public Builder() {
dispatcher = new Dispatcher();
protocols = DEFAULT_PROTOCOLS;
connectionSpecs = DEFAULT_CONNECTION_SPECS;
proxySelector = ProxySelector.getDefault();
cookieJar = CookieJar.NO_COOKIES;
socketFactory = SocketFactory.getDefault();
hostnameVerifier = OkHostnameVerifier.INSTANCE;
certificatePinner = CertificatePinner.DEFAULT;
proxyAuthenticator = Authenticator.NONE;
authenticator = Authenticator.NONE;
connectionPool = new ConnectionPool();
dns = Dns.SYSTEM;
followSslRedirects = true;
followRedirects = true;
retryOnConnectionFailure = true;
connectTimeout = 10_000;
readTimeout = 10_000;
writeTimeout = 10_000;
}
2.2.发起 HTTP 请求
String run(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
OkHttpClient
实现了Call.Factory
,负责根据请求创建新的Call
。
那我们现在就来看看它是如何创建 Call 的:
/**
* Prepares the {@code request} to be executed at some point in the future.
*/
@Override public Call newCall(Request request) {
return new RealCall(this, request);
}
如此看来功劳全在RealCall
类了,下面我们一边分析同步网络请求的过程,一边了解RealCall
的具体内容。
2.2.1.同步网络请求
我们首先看RealCall#execute
:
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed"); // (1)
executed = true;
}
try {
client.dispatcher().executed(this); // (2)
Response result = getResponseWithInterceptorChain(); // (3)
if (result == null) throw new IOException("Canceled");
return result;
} finally {
client.dispatcher().finish