本文基于okhttp3的3.11.0版本进行请求流程的分析:
implementation 'com.squareup.okhttp3:okhttp:3.11.0'
okhttp3的基本请求流程如上图所示,首先构建了网络请求所需的4个类(OkhttpClient,OkhttpClient.Builder,Request,Call),然后通过call.execute()或者call.enqueue(callback)来发起同步请求或者异步请求,下面我们来具体分析一下这两种方式如何进行网络请求的。
okhttp3发起请求的基本方式
1:创建OkhttpClient.Builder与OkhttpClient
OkHttpClient.Builder builder = new OkHttpClient().newBuilder()
.connectTimeout(20,TimeUnit.SECONDS)
.writeTimeout(20,TimeUnit.SECONDS)
.readTimeout(20,TimeUnit.SECONDS);
OkHttpClient okHttpClient = builder.build();
2:构建Request
Request request = new Request.Builder()
.url(url).build();
3:获取Call对象进行同步请求或者异步请求
Call call = okHttpClient.newCall(request);
1:call.execute();//同步请求
2:call.enqueue(callback);//异步请求 callback是okhttp3里面的Callback的实例对象
以上你okhttp3的简略请求步骤,下面我们通过跟踪源码的方式来具体分析一下请求的过程。
1:在获取Call对象是通过OkhttpClient里面的newCall方法进行构建的,newCall方法代码如下
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
在newCall方法内部只调用了RealCall.newRealCall(this, request, false /* for web socket */)方法,进入RealCall中的newRealCall()方法如下:
RealCall call = new RealCall(client, originalRequest, forWebSocket);
call.eventListener = client.eventListenerFactory().create(call);
return call;
在这个方法内部,直接创建了一个RealCall对象,然后返回这个RealCall对象,而且RealCall是Call的子类(final class RealCall implements Call),它实现了Call类里面的方法,所以我们发送请求无论是调用execute()还是enqueue(),实际上都是调用了RealCall内部的方法。
//RealCall类内部的execute()方法
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
try {
client.dispatcher().executed(this);//注释①
Response result = getResponseWithInterceptorChain();//注释②
if (result == null) throw new IOException("Canceled");
return result;
} catch (IOException e) {
eventListener.callFailed(this, e);
throw e;
} finally {
client.dispatcher().finished(this);//注释③
}
}
//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));//注释④
}
从RealCall类中的execute()与enqueue()方法中我们主要关注注释①②③④这四个点就基本上可以知道okhttp3.0网络请求的基本流程了,下面我们大概解释一下上面注释的方法。
(1)注释①中client.dispatcher().executed(this) 这里只是把同步请求的call加入了Dispatcher的任务队列管理中。
(2)注释②中是调用了okhttp中的拦截器链,经过一系列的操作,最终返回响应结果Response。
(3)注释③中是无论请求的结果如何,调用了Dispatcher的finished方法,将当前的请求移出队列。
(4)注释④是异步请求利用了Dispatcher的线程池来处理请求。
从RealCall类可以看出在RealCall内部的enqueue方法和execute方法中,都是通过OkHtt