发送一个异步请求
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最终通过构建线程池来管理异步任务。