我们知道okhttp进行异步请求的时候是一个Okhttp的Call对象执行enqueue进行异步请求,然后会进入Call对象的实现列RealCall的enqueue方法,
RealCall.java:
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
// 获取分发器执行enqueue方法传入AsyncCall对象
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
// AsyncCall是NamedRunnable的子类,会重写NamedRunnable的execute方法
final class AsyncCall extends NamedRunnable {
private final Callback responseCallback;
AsyncCall(Callback responseCallback) {
super("OkHttp %s", redactedUrl());
this.responseCallback = responseCallback;
}
String host() {
return originalRequest.url().host();
}
Request request() {
return originalRequest;
}
RealCall get() {
return RealCall.this;
}
// 一个okhttp请求任务经过分发器最终走到了这里,开始5大拦截器的逻辑
@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);
}
}
}
NamedRunnable.java:
可以看出实现了Runnable接口,run方法执行的时候会执行execute方法,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();
}
请求完成后会走到这句代码client.dispatcher().finished(this);最终会走到以下代码进行请求再次分发
/** Used by {@code AsyncCall#run} to signal completion. */
// 这里是AsyncCall也就是发生异步请求时候走的
void finished(AsyncCall call) {
finished(runningAsyncCalls, call, true);
}
// 这里是RealCall也就是发生同步请求时候走的
/** Used by {@code Call#execute} to signal completion. */
void finished(RealCall call) {
finished(runningSyncCalls, call, false);
}
private void finished(Deque calls, T call, boolean promoteCalls) {
int runningCallsCount;
Runnable idleCallback;
synchronized (this) {
// 将执行完的任务从running队列移除
if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
// 执行promoteCalls进行任务从ready队列到running队列移动
if (promoteCalls) promoteCalls();
runningCallsCount = runningCallsCount();
idleCallback = this.idleCallback;
}
if (runningCallsCount == 0 && idleCallback != null) {
idleCallback.run();
}
}
// 这里就是任务从ready队列到running队列移动的逻辑
private void promoteCalls() {
// 如果正在执行的队列大于maxRequests 就直接返回
if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity.
// 如果ready队列是空的就直接返回
if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote.
// 遍历ready队列
for (Iterator i = readyAsyncCalls.iterator(); i.hasNext(); ) {
AsyncCall call = i.next();
// 每次执行ready队列到running队列的时候判断一下有关同一个Host的请求数是不是到达上限
if (runningCallsForHost(call) < maxRequestsPerHost) {
// 将任务从ready队列移除
i.remove();
// 将任务添加到running队列
runningAsyncCalls.add(call);
// 立即执行这个任务
executorService().execute(call);
}
// 再次判断running队列是否到达上限
if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.
}
}
Dispatcher中的promoteCalls方法就是任务从ready队列到running队列移动的逻辑,其实就是我们的常规思维,running队列如果有了空闲的位置,那么ready中的任务就会加入进去。