BAT大牛带你深度剖析Android 十大开源框架
上一篇文章: Okhttp学习笔记(一) 初步认识&& 源码浅析
成员变量
// 最大请求数 private int maxRequests = 64; // 相同主机最大请求数 private int maxRequestsPerHost = 5; private @Nullable Runnable idleCallback; // 重要 维护的线程池 private @Nullable ExecutorService executorService; // 准备状态中的异步请求队列 private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>(); // 执行中的异步请求队列(包含已经取消但是还没取消的请求) private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>(); // 同步请求队列 private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();核心线程池设置为0,最大线程数设置为Integer的最大值,但是实际上受到maxRequests的限制,并且在空闲60s会自动回收线程;
public synchronized ExecutorService executorService() { if (executorService == null) { executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false)); } return executorService; }直接加入队列
synchronized void executed(RealCall call) { runningSyncCalls.add(call); }以异步请求为例,在实际使用中,我们是通过OkHttpClient的newCall()方法调用的enqueue方法,在Okhttp学习笔记(一)提到过,实际执行的是RealCall类的enqueue方法
// realCall类里调用的dispatcher对象的 enqueue 方法 client.dispatcher().enqueue(new AsyncCall(responseCallback));AsyncCall是一个包装了Callback的Runnable,是RealCall类的内部类,最终线程池会执行AsyncCall的execute方法,通过 getResponseWithInterceptorChain()方法执行请求获得请求结果,并且回调相应的结果,并且会通过RealCall持有的client客户端对象,最终调用Dispatcher的finished方法
final class AsyncCall extends NamedRunnable { ... @Override protected void execute() { boolean signalledCallback = false; try { // 获取拦截器链 获取response Response response = getResponseWithInterceptorChain(); // 判断是否取消 if (retryAndFollowUpInterceptor.isCanceled()) { signalledCallback = true; // 取消则回调onFailure responseCallback.onFailure(RealCall.this, new IOException("Canceled")); } else { signalledCallback = true; // 没取消则回调onResponse 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 { // 捕获到异常 回调到onFailure方法 eventListener.callFailed(RealCall.this, e); responseCallback.onFailure(RealCall.this, e); } } finally { // 调用finished方法 client.dispatcher().finished(this); } } ... }通过回调后最终会走到以下方法:
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!"); if (promoteCalls) promoteCalls(); // 异步会调用的方法 runningCallsCount = runningCallsCount(); // 获取正在执行的请求数 idleCallback = this.idleCallback; } // 执行数为0时,且idleCallback 不为空,执行idleCallback.run(); if (runningCallsCount == 0 && idleCallback != null) { idleCallback.run(); } }除了移除请求,重点看一下异步会执行的promoteCalls方法:
private void promoteCalls() { // 判断是否超过最大请求数,如果超过了就直接结束 if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity. // 判断是否有就绪的队列,没有则返回 if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote. // 遍历就绪等待队列 for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) { AsyncCall call = i.next(); // 如果满足最大同时请求主机数,从就绪队列移除,并添加到运行队列,然后执行请求 if (runningCallsForHost(call) < maxRequestsPerHost) { i.remove(); runningAsyncCalls.add(call); executorService().execute(call); // 最终会执行AsyncCall的execute方法,见上面 } if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity. } }