发送一个异步请求
OkHttpClient okhttpclient = new OkhttpClient.Builder()
.readTimeout(READ_TIME_OUT_VALUE, TimeUnit.SECONDS)
.writeTimeout(WRITE_TIME_OUT_VALUE, TimeUnit.SECONDS)
.build();
Request.Builder builder = new Request.Builder();
Request request = builder.url(httpUrl).get().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());
}
});
我们根据上一篇的经验,从RealCall
入手,查看它的enqueue
的具体实现:
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
我们关注一下最后一行代码,声明了一个新的AsyncCall
并将responseCallback
当做参数传入其中,那表示应该是AsyncCall
发起了真正的请求,我们继续跟踪查看一下:
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;
}
@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
的源码:
/**
* Runnable implementation which always sets its thread name.
*/
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();
}
AsyncCall
继承了NamedRunnable
,NamedRunnable
是Runnable
接口的实现,它的run
方法为当前线程设置了name
并执行了抽象方法execute()
。回过头查看AsyncCall
实现的execute()
方法。最终还是通过getResponseWithInterceptorChain()
方法得到的response
,回到了上一章我们所研究的拦截器链。然后我们回归到RealCall
的enqueue
方法,OkHttpClient
中的dispatcher()
管理AsyncCall
。那可以察觉到,这个dispatcher()
就是多线程控制器。
管理异步请求
我们找到Dispatcher
的源码,查看它的enqueue
方法:
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
代码中的executorService()
真正执行了AsyncCall
。
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;
}
通过代码我们发现,OkHttpClient
最终通过构建线程池来管理异步任务。