OkHttpClient
一般可以通过以下两种方式创建OkhttpClient
OkHttpClient client = new OkHttpClient();
OkHttpClient client = new OkHttpClient.Builder().build();
看一下OkHttpClient构造方法的源码
public OkHttpClient() {
// new Builder()也是做了一些初始化配置
this(new Builder());
}
// 主要利用传入的Builder对象初始了OkHttpClient的成员,还有一些初始化工作
OkHttpClient(Builder builder) {
this.dispatcher = builder.dispatcher;
this.proxy = builder.proxy;
this.protocols = builder.protocols;
this.connectionSpecs = builder.connectionSpecs;// OkHttp连接配置
this.interceptors = Util.immutableList(builder.interceptors);
this.networkInterceptors = Util.immutableList(builder.networkInterceptors);
this.eventListenerFactory = builder.eventListenerFactory;// 一个Call的状态监听器
this.proxySelector = builder.proxySelector;
this.cookieJar = builder.cookieJar;// 默认是没有Cookie的
this.cache = builder.cache;
this.internalCache = builder.internalCache;
this.socketFactory = builder.socketFactory;
boolean isTLS = false;
for (ConnectionSpec spec : connectionSpecs) {
isTLS = isTLS || spec.isTls();
}
if (builder.sslSocketFactory != null || !isTLS) {
this.sslSocketFactory = builder.sslSocketFactory;
this.certificateChainCleaner = builder.certificateChainCleaner;
} else {
X509TrustManager trustManager = Util.platformTrustManager();
this.sslSocketFactory = newSslSocketFactory(trustManager);
this.certificateChainCleaner = CertificateChainCleaner.get(trustManager);
}
if (sslSocketFactory != null) {
Platform.get().configureSslSocketFactory(sslSocketFactory);
}
this.hostnameVerifier = builder.hostnameVerifier; // 安全相关的设置
this.certificatePinner = builder.certificatePinner.withCertificateChainCleaner(
certificateChainCleaner);
this.proxyAuthenticator = builder.proxyAuthenticator;
this.authenticator = builder.authenticator;
this.connectionPool = builder.connectionPool;
this.dns = builder.dns; // 域名解析系统
this.followSslRedirects = builder.followSslRedirects;
this.followRedirects = builder.followRedirects;
this.retryOnConnectionFailure = builder.retryOnConnectionFailure;
this.callTimeout = builder.callTimeout;
this.connectTimeout = builder.connectTimeout;
this.readTimeout = builder.readTimeout;
this.writeTimeout = builder.writeTimeout;
this.pingInterval = builder.pingInterval; // 这个就和WebSocket有关了。为了保持长连接,我们必须间隔一段时间发送一个ping指令进行保活
if (interceptors.contains(null)) {
throw new IllegalStateException("Null interceptor: " + interceptors);
}
if (networkInterceptors.contains(null)) {
throw new IllegalStateException("Null network interceptor: " + networkInterceptors);
}
}
OkHttpClient的静态内部类Builder
主要工作就是封装了外部类需要的参数,并提供了一种比较方便的链式调用方法初始化一个类的成员变量,最后传给外部类完成初始化得到外部对象。
public static final class Builder {
Dispatcher dispatcher;
@Nullable Proxy proxy;
List<Protocol> protocols;
List<ConnectionSpec> connectionSpecs;
final List<Interceptor> interceptors = new ArrayList<>();
final List<Interceptor> networkInterceptors = new ArrayList<>();
EventListener.Factory eventListenerFactory;
ProxySelector proxySelector;
CookieJar cookieJar;
...
// 对成员变量赋初值
public Builder() {
dispatcher = new Dispatcher();
protocols = DEFAULT_PROTOCOLS;
connectionSpecs = DEFAULT_CONNECTION_SPECS;
eventListenerFactory = EventListener.factory(EventListener.NONE);
proxySelector = ProxySelector.getDefault();
if (proxySelector == null) {
proxySelector = new NullProxySelector();
}
cookieJar = CookieJar.NO_COOKIES;
socketFactory = SocketFactory.getDefault();
...
}
// 使用OkHttpClient对成员变量赋值
Builder(OkHttpClient okHttpClient) {
this.dispatcher = okHttpClient.dispatcher;
this.proxy = okHttpClient.proxy;
this.protocols = okHttpClient.protocols;
this.connectionSpecs = okHttpClient.connectionSpecs;
this.interceptors.addAll(okHttpClient.interceptors);
this.networkInterceptors.addAll(okHttpClient.networkInterceptors);
this.eventListenerFactory = okHttpClient.eventListenerFactory;
this.proxySelector = okHttpClient.proxySelector;
this.cookieJar = okHttpClient.cookieJar;
...
}
// 方法返回本身使其可以链式调用
public Builder callTimeout(long timeout, TimeUnit unit) {
callTimeout = checkDuration("timeout", timeout, unit);
return this;
}
...
// 将此Builder对象传入OkHttpClient构造器
public OkHttpClient build() {
return new OkHttpClient(this);
}
}
Request
创建方式:
Request request = new Request.Builder()
.url("http://www.baidu.com")
.get()
.build();
可以看出用的也是Builder模式
public Builder() {
this.method = "GET";
this.headers = new Headers.Builder();
}
Builder(Request request) {
this.url = request.url;
this.method = request.method;
this.body = request.body;
this.tags = request.tags.isEmpty()
? Collections.emptyMap()
: new LinkedHashMap<>(request.tags);
this.headers = request.headers.newBuilder();
}
Call
该对象代表一个准备被执行的请求,Call是可以被取消的,Call对象代表了一个request/response 对(Stream)一个call对象一定只能执行一次
创建方式:
Call call = client.newCall(request);
再来看下OkHttpClient的newCall方法:
@Override public Call newCall(Request request) {
// RealCall是Call的实现类
return RealCall.newRealCall(this, request, false /* for web socket */);
}
OkHttpClient实现了Call接口内部的Factory接口,newCall()是Factory接口的抽象方法。
再来看newRealCall()方法,它是个静态方法:
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
// Safely publish the Call instance to the EventListener.
// 构造方法是私有的 forWebSocket是否用在WebSocket
RealCall call = new RealCall(client, originalRequest, forWebSocket);
call.transmitter = new Transmitter(client, call);
return call;
}
RealCall的execute()
先来看下同步方法
@Override public Response execute() throws IOException {
synchronized (this) {
// 首先判断该call是否被执行过,此处表明call对象一定只能执行一次
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
// Transmitter类是OkHttp的应用层和网络层的一个桥梁类
transmitter.timeoutEnter();
transmitter.callStart();
try {
// client.dispatcher()返回的是client在Builder中初始的dispatcher成员变量
client.dispatcher().executed(this);
// 拿到响应,是拦截器链的开端
return getResponseWithInterceptorChain();
} finally {
client.dispatcher().finished(this);
}
}
dispatcher的executed()
将call加入同步请求的执行队列中
synchronized void executed(RealCall call) {
runningSyncCalls.add(call);
}
getResponseWithInterceptorChain()
将client中的拦截器和默认的拦截器都加入到集合中,将其传入创建了一个RealInterceptorChain
拦截器链。最后返回chain的proceed()的返回值
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
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, transmitter, null, 0,
originalRequest, this, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
boolean calledNoMoreExchanges = false;
try {
Response response = chain.proceed(originalRequest);
if (transmitter.isCanceled()) {
closeQuietly(response);
throw new IOException("Canceled");
}
return response;
} catch (IOException e) {
calledNoMoreExchanges = true;
throw transmitter.noMoreExchanges(e);
} finally {
if (!calledNoMoreExchanges) {
transmitter.noMoreExchanges(null);
}
}
}
dispatcher()的finished()
刚开始在dispatcher.executed()里把call加入到runningSyncCalls这个队列中,这里是将其删除。
void finished(RealCall call) {
finished(runningSyncCalls, call);
}
private <T> void finished(Deque<T> calls, T call) {
Runnable idleCallback;
synchronized (this) {
if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
idleCallback = this.idleCallback;
}
boolean isRunning = promoteAndExecute();
if (!isRunning && idleCallback != null) {
idleCallback.run();
}
}
RealCall的equeue()
@Override public void enqueue(Callback responseCallback) {
// 判断是否执行过
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
transmitter.callStart();
// 把这个回调接口封装成AsyncCall对象
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
dispatcher.enqueue()
同步请求中只有一个队列,而这里有两个,一个为等待队列一个为执行队列
void enqueue(AsyncCall call) {
synchronized (this) {
// 异步请求的就绪队列
readyAsyncCalls.add(call);
// Mutate the AsyncCall so that it shares the AtomicInteger of an existing running call to
// the same host.
// 对异步调用进行变异,使其共享对同一主机的现有运行调用的atomicinteger(原子操作类)
// atomicinteger能保证多个线程对同一个变量不会同时修改
if (!call.get().forWebSocket) {
// 在runningAsyncCalls队列或者readyAsyncCalls队列中找到和call同一主机的call对象
AsyncCall existingCall = findExistingCallWithHost(call.host());
if (existingCall != null) call.reuseCallsPerHostFrom(existingCall);
}
}
promoteAndExecute();
}
dispatcher.promoteAndExecute()
private boolean promoteAndExecute() {
assert (!Thread.holdsLock(this));
// 临时队列
List<AsyncCall> executableCalls = new ArrayList<>();
boolean isRunning;
synchronized (this) {
for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
AsyncCall asyncCall = i.next();
// maxRequests最大并发请求数64
if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity.
// maxRequestsPerHost 每个主机的最大请求数5 当前主机请求数大于等于主机最大请求数
if (asyncCall.callsPerHost().get() >= maxRequestsPerHost) continue; // Host max capacity.
i.remove();
asyncCall.callsPerHost().incrementAndGet();
executableCalls.add(asyncCall);
runningAsyncCalls.add(asyncCall);
}
isRunning = runningCallsCount() > 0;
}
for (int i = 0, size = executableCalls.size(); i < size; i++) {
AsyncCall asyncCall = executableCalls.get(i);
// executorService()返回一个线程池对象
// 真正的异步处理方法
asyncCall.executeOn(executorService());
}
return isRunning;
}
AsyncCall
RealCall里面的内部类
final class AsyncCall extends NamedRunnable {
private final Callback responseCallback;
private volatile AtomicInteger callsPerHost = new AtomicInteger(0);
AsyncCall(Callback responseCallback) {
super("OkHttp %s", redactedUrl());
this.responseCallback = responseCallback;
}
AtomicInteger callsPerHost() {
return callsPerHost;
}
void reuseCallsPerHostFrom(AsyncCall other) {
this.callsPerHost = other.callsPerHost;
}
String host() {
return originalRequest.url().host();
}
Request request() {
return originalRequest;
}
RealCall get() {
return RealCall.this;
}
// 尝试将此异步调用排队到{@code executorservice}。如果执行器已关闭,则此操作将尝试通过将调用报告为失败来进行清理。
void executeOn(ExecutorService executorService) {
assert (!Thread.holdsLock(client.dispatcher()));
boolean success = false;
try {
// 让 ExecutorService 中的某個线程执行这個 Runnable 线程
executorService.execute(this);
success = true;
} catch (RejectedExecutionException e) {
InterruptedIOException ioException = new InterruptedIOException("executor rejected");
ioException.initCause(e);
transmitter.noMoreExchanges(ioException);
responseCallback.onFailure(RealCall.this, ioException);
} finally {
if (!success) {
client.dispatcher().finished(this); // This call is no longer running!
}
}
}
// 和RealCall的execute()方法很像
@Override protected void execute() {
boolean signalledCallback = false;
transmitter.timeoutEnter();
try {
Response response = getResponseWithInterceptorChain();
signalledCallback = true;
responseCallback.onResponse(RealCall.this, response);
} catch (IOException e) {
if (signalledCallback) {
// Do not signal the callback twice!
Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
} else {
responseCallback.onFailure(RealCall.this, e);
}
} finally {
client.dispatcher().finished(this);
}
}
}
AsyncCall继承的NamedRunnable实现Runnable接口。run()里面调用了execute(),它是个抽象方法,具体实现在AsyncCall中。
public abstract class NamedRunnable implements Runnable {
protected final String name;
public NamedRunnable(String format, Object... args) {
this.name = Util.format(format, args);
}
@Override public final void run() {
String oldName = Thread.currentThread().getName();
Thread.currentThread().setName(name);
try {
execute();
} finally {
Thread.currentThread().setName(oldName);
}
}
protected abstract void execute();
}
流程图
Dispatcher
成员变量
private int maxRequests = 64;
private int maxRequestsPerHost = 5;
private @Nullable Runnable idleCallback;
/** Executes calls. Created lazily. */
private @Nullable ExecutorService executorService;
/** Ready async calls in the order they'll be run. */
private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();
/** Running asynchronous calls. Includes canceled calls that haven't finished yet. */
private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();
/** Running synchronous calls. Includes canceled calls that haven't finished yet. */
private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();
executorService()
corePoolSize设置为0表示一旦有闲置的线程就可以回收
public synchronized ExecutorService executorService() {
if (executorService == null) {
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new SynchronousQueue<>(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
}
public ThreadPoolExecutor(
int corePoolSize, // 核心线程数,默认情况下核心线程会一直存活
int maximumPoolSize, // 线程池所能容纳的最大线程数
long keepAliveTime, // 非核心线程的闲置超时时间,超过这个时间就会被回收
TimeUnit unit, // keepAliveTime的单位
BlockingQueue<Runnable> workQueue, // 线程池中的任务队列
ThreadFactory threadFactory // 线程工厂,提供创建新线程的功能
)
Transmitter
OkHttp的应用程序和网络层之间的桥梁。 此类公开了高级应用程序层原语:连接,请求,响应和流。
RealCall负责的是请求发起和执行,Transmitter则负责请求任务的状态、超时时间、生命周期事件的更新以及请求任务背后的连接、连接池的维护管理等。
构造方法参数
- OkHttpClient对象
- RealConnectionPool连接池对象
- RealCall
- EventListener监听对象(则一个请求从发起到结束的所有步骤都会被EventListener“看”到)
- AsyncTimeout超时控制
方法
public Timeout timeout()
返回AsyncTimeout对象
public void timeoutEnter()
创建超时控制
public void timeoutEarlyExit()
在呼叫完成之前停止超时控制
public void callStart()
调用eventListener的callStart方法(绑定call)
public void prepareToConnect(Request request)
准备创建一个流来承载{@code request}。 如果存在连接,则优先使用现有连接。
public boolean canRetry()
是否可以重试
public boolean hasExchange()
是否含有正在执行的交换
public void cancel()
中断请求
public boolean isCanceled()
是否可以中断请求