public void onResponse(Call call, Response response) throws IOException {
Log.d(TAG, "onResponse: " + response.body().string());
}
});
在上述代码中可以看到几个关键类和作用
- OkHttpClient : 用于创建Call对象,源码注释是Factory for {@linkplain Call calls}
- Request :构建我们的请求。源码注释是An HTTP request。
简单直接 - Call :发起我们的http请求
开始分析
OkHttpClient和Request
先看看我们的 OkHttpClient Request
OkHttpClient.java
public OkHttpClient() {
this(new Builder());
}
我们跟进代码可以看到OkHttpClient是一个构建者模式。Request不跟进也可以看到是一个构造者模式。
接下来,我们继续看Call
Call
//OkHttpClient.java
Call newCall(Request request) {
//此处传入我们的OkHttpClient
return RealCall.newRealCall(this, request, false);
}
//RealCall.java
RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
RealCall call = new RealCall(client, originalRequest, forWebSocket);
//Transmitter意为发射器,功能挺杂。注释说是OkHttp的应用程序和网络层之间的桥梁
call.transmitter = new Transmitter(client, call);
return call;
}
在这段代码中,我们可以看到我们得到的Call的实例是RealCall。所以我们enqueue()方法的调用实际是RealCall的方法。
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException(“Already Executed”);
executed = true;
}
transmitter.callStart();
//从我们之前传入OkHttpClient中获取其中的Dispatcher
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
注意这里有一个Dispatcher。这个类负责我们网络请求的调度策略。在这段代码中我们用AsyncCall封装了我们的Callback。AsyncCall 是一个NamedRunnable。在这个NamedRunnable中封装了我们的execute()
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();
}
execute()的具体实现如下
@Override protected void execute() {
boolean signalledCallback = false;
transmitter.timeoutEnter();
try {
//此处得到我们的需要的网络数据
Response response = getResponseWithInterceptorChain();
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 {
// 此处是请求失败回调
responseCallback.onFailure(RealCall.this, e);
}
} catch (Throwable t) {
cancel();
if (!signalledCallback) {
IOException canceledException = new IOException("canceled due to " + t);
canceledException.addSuppressed(t);
responseCallback.onFailure(RealCall.this, canceledException);
}
throw t;
} finally {
client.dispatcher().finished(this);
}
}
在上面这个方法中我们可以看到请求的结果是如何获得,那么这个runnable任务是怎么调度执行的呢?我们就得回过头看看Dispatcher类的enqueue()方法做了啥
void enqueue(AsyncCall call) {
synchronized (this) {
readyAsyncCalls.add(call);
if (!call.get().forWebSocket) {
//如果有请求同一host的AsyncCall就进行复用
AsyncCall existingCall = findExistingCallWithHost(call.host());
if (existingCall != null) call.reuseCallsPerHostFrom(existingCall);
}
}
推动执行方法
promoteAndExecute();
}
private boolean promoteAndExecute() {
assert (!Thread.holdsLock(this));
List executableCalls = new ArrayList<>();
boolean isRunning;
synchronized (this) {
//循环收集可以执行的AsyncCall
for (Iterator i = readyAsyncCalls.iterator(); i.hasNext(); ) {
AsyncCall asyncCall = i.next();
if (runningAsyncCalls.size() >= maxRequests) break; // 最大执行的call大于64 跳出
if (asyncCall.callsPerHost().get() >= maxRequestsPerHost) continue; // 请求同一host的call > 5 跳过
i.remove();
asyncCall.callsPerHost().incrementAndGet();
executableCalls.add(asyncCall);
runningAsyncCalls.add(asyncCall);
}
isRunning = runningCallsCount() > 0;
}
//把可以执行的AsyncCall,统统执行
for (int i = 0, size = executableCalls.size(); i < size; i++) {
AsyncCall asyncCall = executableCalls.get(i);
//executorService()返回一个线程池
asyncCall.executeOn(executorService());
}
return isRunning;
}
void executeOn(ExecutorService executorService) {
boolean success = false;
try {
//线程池运行Runnable,执行run,调用前面提到的AsyncCall.execute
executorService.execute(this);
success = true;
} catch (RejectedExecutionException e) {
InterruptedIOException ioException = new InterruptedIOException(“executor rejected”);
ioException.initCause(e);
transmitter.noMoreExchanges(ioException);
//失败回调
responseCallback.onFailure(RealCall.this, ioException);
} finally {
if (!success) {
//结束
client.dispatcher().finished(this);
}
}
}
到了这里我们的AsyncCall就顺利执行了。整个Okhttp代码的主干就在这里。接下来我们继续探讨okhttp这个框架的一些细节设计
拦截器链
前边得到Response的地方,我们调用了getResponseWithInterceptorChain()。但没细讲,这个部分就是大名鼎鼎的okhttp的拦截器链。
//RealCall.java
}
到了这里我们的AsyncCall就顺利执行了。整个Okhttp代码的主干就在这里。接下来我们继续探讨okhttp这个框架的一些细节设计
拦截器链
前边得到Response的地方,我们调用了getResponseWithInterceptorChain()。但没细讲,这个部分就是大名鼎鼎的okhttp的拦截器链。
//RealCall.java