上一篇文章已经对Request相关的类进行了详细的学习,后面我发现Okhttp这种底层框架一个类一个类看没什么用,所以这篇文章开始就只对Okhttp的整体流程作一个学习
1.简单的get请求
Request request = new Request.Builder()
.url("https://www.baidu.com/")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
我们来看一下RealCall中的enqueue的逻辑看一下,
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
这个方法调用Dispatcher的enqueue方法
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
//正在运行的异步任务队列数量小于最大请求数,线程池执行该任务
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
//把该方法放到异步任务准备队列中
readyAsyncCalls.add(call);
}
}
线程池执行该异步任务,会执行异步任务的run方法,run方法中调用了execute抽象方法,我们来看一下这个方法的实现
@Override protected void execute() {
boolean signalledCallback = false;
try {
//由getResponseWithInterceptorChain()来执行网络请求,得到response
Response response = getResponseWithInterceptorChain();
if (retryAndFollowUpInterceptor.isCanceled()) {
signalledCallback = true;
//失败后回调Callback的onFailure方法
responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
} else {
signalledCallback = true;
//成功后回调CallBack的onResponse方法
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 {
//最后调用Dispatcher的finish方法
client.dispatcher().finished(this);
}
}
我们先来看finish方法,后面再去看getResponseWithInterceptorChain(),来解决简单的再去看复杂的
void finished(AsyncCall call) {
finished(runningAsyncCalls, call, true);
}
private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
int runningCallsCount;
Runnable idleCallback;
synchronized (this) {
if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
//promoteCalls()该方法会去从异步准备运行的队列中去取任务去执行
if (promoteCalls) promoteCalls();
//得到异步和同步任务正在执行数
runningCallsCount = runningCallsCount();
idleCallback = this.idleCallback;
}
//如果设置了该线程,执行回调线程
if (runningCallsCount == 0 && idleCallback != null) {
idleCallback.run();
}
}
走完一个流程后我们来看一下getResponseWithInterceptorChain()方法的实现细节,这个方法在call.execute()也调用到了,OkHttp中真正发出网络请求,解析返回结果的,就是这个方法
private Response getResponseWithInterceptorChain() throws IOException {
//构建全栈拦截器
List interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());//自定义拦截器
interceptors.add(retryAndFollowUpInterceptor);//重试拦截器
interceptors.add(new BridgeInterceptor(client.cookieJar()));//桥接拦截器
interceptors.add(new CacheInterceptor(client.internalCache()));//缓存拦截器
interceptors.add(new ConnectInterceptor(client));//连接拦截器
if (!retryAndFollowUpInterceptor.isForWebSocket()) {
interceptors.addAll(client.networkInterceptors());//用户预定义的网络拦截器
}
interceptors.add(new CallServerInterceptor(
retryAndFollowUpInterceptor.isForWebSocket()));//调用服务拦截器
//内部通过责任链模式来使用拦截器
Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);//获取Response
}
这么多的拦截器,看着肯定很懵逼吧,是的我就是这样。我们就一个一个的来看吧
RetryAndFollowUpInterceptor
重试与重定向拦截器,用来实现重试和重定向功能,
内部通过
while(true)死循环来进行重试获取Response(有重试上限,超过会抛出异常)。
followUpRequest主要用来根据响应码来判断属于哪种行为触发的重试和重定向(比如未授权,超时,重定向等),然后构建响应的Request进行下一次请求。当然,如果没有触发重新请求就会直接返回Response。
BridgeInterceptor