我们通过一个简单的post请求,来分析整个网络请求的过程:
OkHttpClient.Builder builder = new OkHttpClient.Builder();
OkHttpClient okHttpClient = builder.build();
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
//同步请求
Response response=okHttpClient.newCall(request).execute();
//异步请求
Response response=okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
- 通过OkHttpClient.Builder(建造者模式)创建okHttpClient对象
- okHttpClient调用newCall方法,创建一个RealCall对象
RealCall.new RealCall(this, request, false /* for web socket */);
- RealCall对象通过execute方法来完成同步请求,通过enqueue方法完成异步请求,他们都是调用OkHttpClient对象的Dispatcher来完成网络请求,区别是:enqueue方式是通过ExecutorService来执行AsyncCall,而execute不使用ExecutorService,下面看下RealCall的enqueue方法:
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
transmitter.callStart();
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
- Dispatcher是网络请求调度器,里面有三个双端队列(同步、异步和等待中),把请求添加到一个预请求双端队列中,然后判断正在执行的请求是否大于最大请求数,如果不大于,则把请求移到正在另一个正在请求的双端队列中,通过线程池来执行AsyncCall ,下面是异步请求代码:
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
- 下面看下AsyncCall 的execute方法,里面是通过getResponseWithInterceptorChain方法来获取Response 对象
@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 {
responseCallback.onFailure(RealCall.this, e);
}
} finally {
client.dispatcher().finished(this);
}
}
- RealInterceptorChain的proceed方法,里面会获取拦截器,调用拦截器的intercept方法,拦截器的intercept方法的又会调用RealInterceptorChain的proceed方法,这样就形成了递归,一直到所有的拦截器intercept方法走完
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
RealConnection connection) throws IOException {
if (index >= interceptors.size()) throw new AssertionError();
calls++;
// If we already have a stream, confirm that the incoming request will use it.
if (this.httpCodec != null && !this.connection.supportsUrl(request.url())) {
throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
+ " must retain the same host and port");
}
// If we already have a stream, confirm that this is the only call to chain.proceed().
if (this.httpCodec != null && calls > 1) {
throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
+ " must call proceed() exactly once");
}
// Call the next interceptor in the chain.
RealInterceptorChain next = new RealInterceptorChain(
interceptors, streamAllocation, httpCodec, connection, index + 1, request);
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);
// Confirm that the next interceptor made its required call to chain.proceed().
if (httpCodec != null && index + 1 < interceptors.size() && next.calls != 1) {
throw new IllegalStateException("network interceptor " + interceptor
+ " must call proceed() exactly once");
}
// Confirm that the intercepted response isn't null.
if (response == null) {
throw new NullPointerException("interceptor " + interceptor + " returned null");
}
return response;
}