首先我们来看一段代码:
String url = "http://wwww.baidu.com";
OkHttpClient okHttpClient = new OkHttpClient();
final Request request = new Request.Builder()
.url(url)
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d(TAG, "onFailure: ");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.d(TAG, "onResponse: " + response.body().string());
}
});
我们直接来看这一段
Call call = okHttpClient.newCall(request);
研究okhttpclient这个类之前,我们先来看看他都实现了那些类。
public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
}
我们这里只看 Call.Factory,webSocket.Factory一般app用不到。
public interface Call extends Cloneable {
...
Response execute() throws IOException;//同步请求接口
void enqueue(Callback responseCallback);//异步请求接口
...
interface Factory {
Call newCall(Request request);
}
}
这里我们就很明白newcall 的来历了。废话不多说直接看okhttpclient的newcall方法。
public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
}
然后进入realcall:
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
// Safely publish the Call instance to the EventListener.
RealCall call = new RealCall(client, originalRequest, forWebSocket);
call.eventListener = client.eventListenerFactory().create(call);
return call;
}
private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
this.client = client;
this.originalRequest = originalRequest;
this.forWebSocket = forWebSocket;
this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);
}
这里我们看到比较重要的一个类RetryAndFollowUpInterceptor。重试/重定向 拦截器。这里我们不多做解析,后面的章节我们会详细的分析。
接下来就是
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d(TAG, "onFailure: ");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.d(TAG, "onResponse: " + response.body().string());
}
});
从上面的分析我们知道,这里的call 是RealCall,so...我们去看一下他的enqueue方法。(当然这里我们也看见了RealCall也是实现的Call接口)。
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
...
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
一个同步锁是否执行过的判断。然后我们来看一下这段代码:
client.dispatcher().enqueue(new AsyncCall(responseCallback));
这样,我们需求进入到okhttpclient中,
public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
public Dispatcher dispatcher() {
return dispatcher;
}
public static final class Builder {
Dispatcher dispatcher;
...
}
public Builder() {
dispatcher = new Dispatcher();
...
}
}
接着,我们来看看Dispatcher。
public final class Dispatcher {
private int maxRequests = 64;
private int maxRequestsPerHost = 5;
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<>();
public Dispatcher(ExecutorService executorService) {
this.executorService = executorService;
}
...
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 enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
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);
}
if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.
}
}
synchronized void executed(RealCall call) {
runningSyncCalls.add(call);
}
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;
}
if (runningCallsCount == 0 && idleCallback != null) {
idleCallback.run();
}
}
}
好吧有点多,我们来看看都是啥,首先Dispatcher是一个调度器maxRequests最大请求为64,maxRequestsPerHost每个主机最多请求数为5。
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;
}
生成了一个可以无限大的 存活周期60s的线程池。
private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();
private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();
private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();
三个队列,一个同步请求的队列runningSyncCalls,两个异步请求使用的队列(readyAsyncCalls为等待请求的队列,runningAsyncCalls为正在请求的队列)。
好了继续enqueue方法,很明显,我们要先看一下AsyncCall。
final class AsyncCall extends NamedRunnable {
...
Request request() {
return originalRequest;
}
...
@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);
}
}
}
这是一个可以命名的线程。最重要的方法execute。因为设计到okhttpclient的拦截机制,我们后面会详细分析。
现在我们终于来到了
client.dispatcher().enqueue(new AsyncCall(responseCallback));
我们进入到dispatcher可知:
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
如果runningAsyncCalls大小小于64,这个接口主机请求小于5 ,这时就会把call 添加到正在请求的队列中,并且通过executorService的调度执行AsyncCall的execute方法,最终通过 Response response = getResponseWithInterceptorChain(); 获取到Response通过Callback返回。