OKHTTP源码解读
文章目录
一、DISPATCHER(分发器)
-
OkHttpClient对象的创建:
OKHttpClient client=new OkHttpClient.Builder().build();
采用Builder设计模式创建client对象。client封装了几个重要的成员属于和方法。
-
Request对象request也是通过Builder模式生成,对象内部封装了Http请求的参数
-
通过调用client对象的newCall(Request request)方法返回Call对象
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
在newCall方法内部调用了RealCall对象的静态方法返回一个Call接口的实现类RealCall对象。
4. RealCall对象主要成员属性和方法有
RealCall中有一个内部类AsyncCall,AsyncCall中就有一个很重要的成员变量responseCallback,就是我们网络请求的回调接口Callback,AsyncCall继承自NamedRunnable,而NamedRunnable是抽象类,并且是Runnable接口的实现类,即RealCall的内部类AsyncCall是一个线程类
5. `call.execute()同步请求方法的执行过程
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
try {
client.dispatcher().executed(this);//通过client.dispatcher获取Dispatcher对象调用其executed()方法
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} catch (IOException e) {
eventListener.callFailed(this, e);
throw e;
} finally {
client.dispatcher().finished(this);
}
}
主要执行逻辑为:
1.client.dispatcher().executed(this);//通过client.dispatcher()获取OKHttpClient的成员变量Dispatcher对象dispatcher,然后调用其executed()方法。对象dispatcher在OkHttpClient的Builder()方法中被初始化。Dispacher类的主要成员属性和方法有
调用dispatcher.executed(RealCall call)的执行逻辑如下,即将请求添加到运行时同步请求队列中
synchronized void executed(RealCall call) {
runningSyncCalls.add(call);
}
2.Response result = getResponseWithInterceptorChain();//获取Response对象
3.client.dispatcher().finished(this);同步请求最终调用到
/** Used by {@code Call#execute} to signal completion. */
void finished(RealCall call) {
finished(runningSyncCalls, call, false);
}
private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
int runningCallsCount;
Runnable idleCallback;
synchronized (this) {
//请求完成 移除请求任务
if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
//根据传入的promoteCalls判断是否执行promoteCalls()方法,
//同步传入的false,异步传入的true
if (promoteCalls) promoteCalls();
runningCallsCount = runningCallsCount();
idleCallback = this.idleCallback;
}
if (runningCallsCount == 0 && idleCallback != null) {
idleCallback.run();
}
}
请求完成后调用了finished从队列中移除call请求任务
6.call.enqueue()异步请求方法的执行过程
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
首先判断运行时异步请求队列的大小小于64且每个主机的连接数小于5时将请求添加到运行时请求队列,采用线程池执行AsyncCall任务,即会执行AsyncCall的run方法中的execute()方法
@Override protected void execute() {
boolean signalledCallback = false;
try {
Response response = getResponseWithInterceptorChain();
if (retryAndFollowUpInterceptor.isCanceled()) {
signalledCallback = true;
responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
} else {
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 {
eventListener.callFailed(RealCall.this, e);
responseCallback.onFailure(RealCall.this, e);
}
} finally {
client.dispatcher().finished(this);
}
}
其主要执行了
1.Response response = getResponseWithInterceptorChain();
2. client.dispatcher().finished(this);在这个方法中主要的逻辑执行为:
//异步请求最终调用
/** Used by {@code AsyncCall#run} to signal completion. */
void finished(AsyncCall call) {
finished(runningAsyncCalls, call, true);
}
private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
int runningCallsCount;
Runnable idleCallback;
synchronized (this) {
//请求完成 移除请求任务
if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
//根据传入的promoteCalls判断是否执行promoteCalls()方法,
//同步传入的false,异步传入的true
if (promoteCalls) promoteCalls();
runningCallsCount = runningCallsCount();
idleCallback = this.idleCallback;
}
if (runningCallsCount == 0 && idleCallback != null) {
idleCallback.run();
}
}
//异步请求的promoteCalls为true才会调用到该方法
private void promoteCalls() {
//已经达到最大并发数直接return
if (runningAsyncCalls.size() >= maxRequests)