本文,将对Okhttp
整体流程进行分析.
本文若无特殊说明,采用的okhttp
版本为 3.10.0
创建 OkHttpClient
实例的两种方式:
代码片1
OkHttpClient okHttpClient = new OkHttpClient();
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
我们先研究第一种构造方式,也是默认的方式,我们点击OkHttpClient方法进去:
OkHttpClient.class
代码片2
public OkHttpClient() {
this(new Builder());
}
发现是一个类构造方法,this
其实就是指的是OkHttpClient
,也就是如下方法:
OkHttpClient.class
代码片3
OkHttpClient(Builder builder) {
this.dispatcher = builder.dispatcher;
this.proxy = builder.proxy;
this.protocols = builder.protocols;
this.connectionSpecs = builder.connectionSpecs;
this.interceptors = Util.immutableList(builder.interceptors);
this.networkInterceptors = Util.immutableList(builder.networkInterceptors);
this.eventListenerFactory = builder.eventListenerFactory;
this.proxySelector = builder.proxySelector;
this.cookieJar = builder.cookieJar;
//删除多行代码
}
然后顺理成章的看一下new Builder()
方法
OkHttpClient.class
代码片4
public Builder() {
dispatcher = new Dispatcher();
protocols = DEFAULT_PROTOCOLS;
connectionSpecs = DEFAULT_CONNECTION_SPECS;
eventListenerFactory = EventListener.factory(EventListener.NONE);
proxySelector = ProxySelector.getDefault();
cookieJar = CookieJar.NO_COOKIES;
socketFactory = SocketFactory.getDefault();
hostnameVerifier = OkHostnameVerifier.INSTANCE;
certificatePinner = CertificatePinner.DEFAULT;
proxyAuthenticator = Authenticator.NONE;
authenticator = Authenticator.NONE;
connectionPool = new ConnectionPool();
dns = Dns.SYSTEM;
followSslRedirects = true;
followRedirects = true;
retryOnConnectionFailure = true;
connectTimeout = 10_000;
readTimeout = 10_000;
writeTimeout = 10_000;
pingInterval = 0;
}
上述代码是做一些初始化配置.
现在来看另一个种构造方式:
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
点开build()
方法,代码如下:
OkHttpClient.class
代码片5
public OkHttpClient build() {
return new OkHttpClient(this);
}
这里需要我们注意的是Builder
它是静态内部类.
上面讲到了OkHttpClient
的两种构造方式,通过查看源码,两种方式的配置是相同的,下面具体看一下到底配置了什么(即代码片4):
具体的配置内容,在下面代码中已经注释.
OkHttpClient.class
代码片6
public Builder() {
dispatcher = new Dispatcher(); //调度器,执行异步请求时的策略
protocols = DEFAULT_PROTOCOLS; //OKHTTP实现的协议LIST
connectionSpecs = DEFAULT_CONNECTION_SPECS; //TLS版本与连接协议
eventListenerFactory = EventListener.factory(EventListener.NONE); //监听器
proxySelector = ProxySelector.getDefault(); //代理选择器
cookieJar = CookieJar.NO_COOKIES; //cookie
socketFactory = SocketFactory.getDefault(); //socket 工厂
hostnameVerifier = OkHostnameVerifier.INSTANCE; //主机name验证
certificatePinner = CertificatePinner.DEFAULT;
proxyAuthenticator = Authenticator.NONE; //代理验证
authenticator = Authenticator.NONE; //验证
connectionPool = new ConnectionPool(); //连接池
dns = Dns.SYSTEM; //dns域名
followSslRedirects = true; //安全套接层重定向
followRedirects = true; //本地重定向
retryOnConnectionFailure = true; //错误重连
connectTimeout = 10_000; //connect超时
readTimeout = 10_000; //read超时
writeTimeout = 10_000; //write超时
pingInterval = 0; //ping超时
}
当我们构建完OkHttpClient
对象,需要构造Request
对象,构造方式如下:
Request request = new Request.Builder()
.url("https://www.wanandroid.com/article/list/1/json")
.get()//默认就是GET请求,可以不写
.build();
拿POST
提交表单请求,这时就需要声明一个RequestBody
对象了
RequestBody requestBody = new FormBody.Builder()
.add("username", "weibuzudao")
.add("password", "123456")
.build();
Request request = new Request.Builder()
.url("https://www.wanandroid.com/user/login")
.post(requestBody)
.build();
看到上面代码是不是很熟悉?和OkHttpClient
很相似, 没错 Request
的构建也是Builder
模式!
我们点击Request
源码进去,果然 其中有静态的Builder
内部类:
Request.class
代码片7
public static class Builder {
HttpUrl url;
String method;
Headers.Builder headers;
RequestBody body;
//这里配置默认的参数
public Builder() {
this.method = "GET"; //默认是GET请求
this.headers = new Headers.Builder();
}
//这里通过另外一个Request配置参数
Builder(Request request) {
this.url = request.url;
this.method = request.method;
//...
}
//省略部分代码
// 配置完参数后,通过Builder的参数创建一个Request
public Request build() {
if (url == null) throw new IllegalStateException("url == null");
return new Request(this);
}
}
从代码看到了 如果没有声明,默认是Get
请求 this.method = "GET"
,至于url
等字段需要我们自己去配置:
请求访问的url
,可以传String
与URL
具体方法如下:
Request.class
代码片8
public Builder url(HttpUrl url) {
if (url == null) throw new NullPointerException("url == null");
this.url = url;
return this;
}
/**
* Sets the URL target of this request.
*
* @throws IllegalArgumentException if {@code url} is not a valid HTTP or HTTPS URL. Avoid this
* exception by calling {@link HttpUrl#parse}; it returns null for invalid URLs.
*/
public Builder url(String url) {
if (url == null) throw new NullPointerException("url == null");
// Silently replace web socket URLs with HTTP URLs.
if (url.regionMatches(true, 0, "ws:", 0, 3)) {
url = "http:" + url.substring(3);
} else if (url.regionMatches(true, 0, "wss:", 0, 4)) {
url = "https:" + url.substring(4);
}
HttpUrl parsed = HttpUrl.parse(url);
if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url);
return url(parsed);
}
/**
* Sets the URL target of this request.
*
* @throws IllegalArgumentException if the scheme of {@code url} is not {@code http} or {@code
* https}.
*/
public Builder url(URL url) {
if (url == null) throw new NullPointerException("url == null");
HttpUrl parsed = HttpUrl.get(url);
if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url);
return url(parsed);
}
请求类型 String method
,支持多种请求类型
Request.class
代码片9
public Builder get() {
return method("GET", null);
}
public Builder head() {
return method("HEAD", null);
}
public Builder post(RequestBody body) {
return method("POST", body);
}
public Builder delete(@Nullable RequestBody body) {
return method("DELETE", body);
}
public Builder delete() {
return delete(Util.EMPTY_REQUEST);
}
public Builder put(RequestBody body) {
return method("PUT", body);
}
public Builder patch(RequestBody body) {
return method("PATCH", body);
}
Headers.Builder Http
消息的头字段
前面看到了, 我们在初始化Request
的时候 同时初始化了headers
, this.headers = new Headers.Builder()
(代码片7第9行代码)
可以通过 header
addHeader
removeHeader
headers
方法做一些操作
Request.class
代码片10
public Builder header(String name, String value) {
headers.set(name, value);
return this;
}
public Builder addHeader(String name, String value) {
headers.add(name, value);
return this;
}
public Builder removeHeader(String name) {
headers.removeAll(name);
return this;
}
public Builder headers(Headers headers) {
this.headers = headers.newBuilder();
return this;
}
RequestBody
类型,它是抽象类, 有些请求需要我们传入body
实例 ,我们在通过源码来看一下:
如果是GET
请求,body
对象传的是null
Get
与head
方法不能传body
对象 ,其他method
是可以的
public Builder get() {
return method("GET", null);
}
public Builder head() {
return method("HEAD", null);
}
如果是POST
delete
put
patch
请求,就需要我们去设定了:
public Builder post(RequestBody body) {
return method("POST", body);
}
public Builder delete(@Nullable RequestBody body) {
return method("DELETE", body);
}
public Builder delete() {
return delete(Util.EMPTY_REQUEST);
}
public Builder put(RequestBody body) {
return method("PUT", body);
}
public Builder patch(RequestBody body) {
return method("PATCH", body);
}
首先我们看一下RequestBody
如何初始化??拿提交表单举例:
RequestBody requestBody = new FormBody.Builder()
.add("username", "weibuzudao")
.add("password", "123456")
.build();
Request request = new Request.Builder()
.url("https://www.wanandroid.com/user/login")
.post(requestBody)
.build();
不出所料,也是Builder
模式,而且RequestBody
是抽象类, FormBody
是RequestBody
的其中一种实现类 ,另一个实现类是MultipartBody
.
public final class FormBody extends RequestBody {
public final class MultipartBody extends RequestBody {
RequestBody
源码如下:
RequestBody.class
public abstract class RequestBody {
/** Returns the Content-Type header for this body. */
public abstract @Nullable MediaType contentType();
/**
* Returns the number of bytes that will be written to {@code sink} in a call to {@link #writeTo},
* or -1 if that count is unknown.
*/
public long contentLength() throws IOException {
return -1;
}
/** Writes the content of this request to {@code sink}. */
public abstract void writeTo(BufferedSink sink) throws IOException;
/**
* Returns a new request body that transmits {@code content}. If {@code contentType} is non-null
* and lacks a charset, this will use UTF-8.
*/
public static RequestBody create(@Nullable MediaType contentType, String content) {
Charset charset = Util.UTF_8;
if (contentType != null) {
charset = contentType.charset();
if (charset == null) {
charset = Util.UTF_8;
contentType = MediaType.parse(contentType + "; charset=utf-8");
}
}
byte[] bytes = content.getBytes(charset);
return create(contentType, bytes);
}
/** Returns a new request body that transmits {@code content}. */
public static RequestBody create(
final @Nullable MediaType contentType, final ByteString content) {
return new RequestBody() {
@Override public @Nullable MediaType contentType() {
return contentType;
}
@Override public long contentLength() throws IOException {
return content.size();
}
@Override public void writeTo(BufferedSink sink) throws IOException {
sink.write(content);
}
};
}
/** Returns a new request body that transmits {@code content}. */
public static RequestBody create(final @Nullable MediaType contentType, final byte[] content) {
return create(contentType, content, 0, content.length);
}
/** Returns a new request body that transmits {@code content}. */
public static RequestBody create(final @Nullable MediaType contentType, final byte[] content,
final int offset, final int byteCount) {
if (content == null) throw new NullPointerException("content == null");
Util.checkOffsetAndCount(content.length, offset, byteCount);
return new RequestBody() {
@Override public @Nullable MediaType contentType() {
return contentType;
}
@Override public long contentLength() {
return byteCount;
}
@Override public void writeTo(BufferedSink sink) throws IOException {
sink.write(content, offset, byteCount);
}
};
}
/** Returns a new request body that transmits the content of {@code file}. */
public static RequestBody create(final @Nullable MediaType contentType, final File file) {
if (file == null) throw new NullPointerException("content == null");
return new RequestBody() {
@Override public @Nullable MediaType contentType() {
return contentType;
}
@Override public long contentLength() {
return file.length();
}
@Override public void writeTo(BufferedSink sink) throws IOException {
Source source = null;
try {
source = Okio.source(file);
sink.writeAll(source);
} finally {
Util.closeQuietly(source);
}
}
};
}
}
核心方法有三个:
我们首先看一下在哪用到了Call:
Call call = okHttpClient.newCall(request);
无论是get
还是post
请求 都要生成call对象,在上面我们发现call
实例需要一个okHttpClient
与request
实例 ,我们先点进Call
类去看看:
Call.class
public interface Call extends Cloneable {
//返回当前请求
Request request();
//同步请求方法,此方法会阻塞当前线程直到请求结果放回
Response execute() throws IOException;
//异步请求方法,此方法会将请求添加到队列中,然后等待请求返回
void enqueue(Callback responseCallback);
//取消请求
void cancel();
//判断请求是否在执行
boolean isExecuted();
//判断请求是否取消
boolean isCanceled();
//返回请求的超时时间
Timeout timeout();
//克隆一个新的请求
Call clone();
//工厂接口. Factory中有一个newCall(Request)方法,这说明Call是通过工厂模式创建,而OkHttpClient实现了Call.Factory接口,重写了newCall(Request)方法,返回了Call的具体实现类RealCall
interface Factory {
Call newCall(Request request);
}
}
我们发现Call
是个接口, 并定义了一些方法(方法含义在注释上)。
.
我们继续看newCal()
方法
OkHttpClient.class
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
继续点击newRealCall()
去:
RealCall.class (RealCall implements Call)
private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
this.client = client;
this.originalRequest = originalRequest;
this.forWebSocket = forWebSocket;
this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);
}
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
// Safely publish the Call instance to the EventListener.
RealCall call = new RealCall(client, originalRequest, forWebSocket);
call.eventListener = client.eventListenerFactory().create(call);
return call;
}
从代码中我们发现在newRealCall()
中初始化了RealCall
,RealCall
中初始化了retryAndFollowUpInterceptor
:
OkHttpClient
实例Request
websocket
通信RealCall.class
@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);
}
}
从上面代码得知步骤:
(1).通过 synchronized
保证线程同步,判断是否已经执行过 ,如果是直接抛异常
(2). captureCallStackTrace()
; 字面意思:捕获调用堆栈跟踪,我们通过源码发现里面涉及到了
retryAndFollowUpInterceptor
(3). eventListener
回调CallStart()
(4). client.dispatcher().executed(this)
; 看到了dispatcher
是不是很熟悉?之前在分析okhttpClient
初始化的时候遇到了,我们点击executed()
方法进去:
Dispatcher(中文:调度).class
synchronized void executed(RealCall call) {
runningSyncCalls.add(call);
}
Dispatcher.class
private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();
发现把我们传进来的realcall
放到了runningSyncCalls
队列中,从字面意思来说就是正在运行的同步的调用队列中,为什么说是队列呢?
Deque
即双端队列。是一种具有队列和栈的性质的数据结构。双端队列中的元素可以从两端弹出,相比lis增加[ ] 运算符重载。
(5).我们回到execute()
继续往下分析,剩下的代码我们提取出三行代码:
Response result =getResponseWithInterceptorChain()
; 生成一个Response 实例
eventListener.callFailed(this, e)
; :eventListener的callFailed回调
client.dispatcher().finished(this)
; :dispatcher实例的finished方法
不难看出,getResponseWithInterceptorChain()
一定是此方法中的核心,字面意思是获取拦截器链的响应,这就明白了,就是通过拦截器链处理后返回Response
RealCall.class
Response getResponseWithInterceptorChain() throws IOException {
//拦截器的添加
List<Interceptor> 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 (!forWebSocket) {
interceptors.addAll(client.networkInterceptors()); //网络拦截器
}
//添加的最后一个拦截器是CallServerInterceptor
interceptors.add(new CallServerInterceptor(forWebSocket)); //调用服务器拦截器
//创建一个RealInterceptorChain,传入了interceptors和Request
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
originalRequest, this, eventListener, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
return chain.proceed(originalRequest);
}
}
getResponseWithInterceptorChain()方法最终返回一个Response,也就是网络请求的响应,该方法中首先把用户自定义的拦截器和okhttp默认的拦截器封装到一个List中,然后创建RealInterceptorChain并执行proceed(Request)方法处理请求
从上面代码不难看出, 对最初的request
做了层层拦截,每个拦截器的原理我们放在以后的章节去讲, 这里就不展开了!
这里需要强调的一下 interceptors.addAll(client.interceptors())
; ,client.interceptors()
是我们自定义的拦截器 它是在哪定义的?如何添加?我们去OkHttpClient
类中发现:
OkHttpClient.class
/**
* Returns a modifiable list of interceptors that observe the full span of each call: from
* before the connection is established (if any) until after the response source is selected (either the origin server, cache, or both).
*
* 返回一个可修改的拦截器列表,这些监听器观察每个调用的整个范围:从建立连接之前(如果有)直到选择响应源之后*(源服务器,高速缓存或两者都有)
*/
public List<Interceptor> interceptors() {
return interceptors;
}
public Builder addInterceptor(Interceptor interceptor) {
if (interceptor == null) throw new IllegalArgumentException("interceptor == null");
interceptors.add(interceptor);
return this;
}
可以通过初始化okHttpClient
实例 .addInterceptor
的形式 添加。
另外这里涉及到了责任链设计模式,下节具体讲!
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e(TAG, "onFailure: ");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.e(TAG, "onResponse: " + response.body().string());
}
});
点击enqueue()
查看:
RealCall.class
@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));
}
(1).通过 synchronized
保证线程同步,判断是否已经执行过 ,如果是直接抛异常
(2). captureCallStackTrace()
; 字面意思:捕获调用堆栈跟踪,我们通过源码发现里面涉及到了retryAndFollowUpInterceptor
(3). eventListener
回调CallStart()
(4). client.dispatcher().enqueue(new AsyncCall(responseCallback));
调用了Dispatcher.enqueue()
并传入了一个new AsyncCall(responseCallback)
实例,点击AsyncCall
查看:
RealCall.class
AsyncCall
是RealCall
的内部类!
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);
}
}
}
AsyncCall
继承了NamedRunnable
,我们看下NamedRunnable
是什么:
NamedRunnable.class
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();
}
原来NamedRunnable
实现了Runnable
接口 是个线程类,在run()
中 添加了抽象的execute()
;方法,看到这里 我们应该有一个反应,那就是AsyncCall
中具体的execute()
应该在子线程执行.
我们继续分析,client.dispatcher().enqueue(new AsyncCall(responseCallback))
; 点击进入enqueue()
:
Dispatcher.class
private int maxRequests = 64;
private int maxRequestsPerHost = 5;
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
runningAsyncCalls
正在运行的异步请求的队列maxRequests
最大的请求数 64maxRequestsPerHost
host最大请求数 5 (可以通过Get
与Set
方式自定义设置)如果正在运行的异步请求的队列大小低于64并且 正在请求的host数量低于5,就会执行(满足条件)
runningAsyncCalls.add(call);
executorService().execute(call);
这里把 AsyncCall
实例添加到 runningAsyncCalls
中。
ExecutorService
表示线程池 继续看 executorService()
:
Dispatcher.class
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;
}
其实就是生成了executorService
实例,这就明白了,AsyncCall
实例放入线程池中执行了!
如果不满足上面的请求数等条件:
readyAsyncCalls.add(call);
就会被添加到一个等待就绪的异步请求队列中,目的是什么呢???当然是等待时机再次添加到runningAsyncCalls
中并放入线程池中执行,这块逻辑在 AsyncCall
类中的 execute()
至于原因我们继续往下看!
刚才我们说了,如果条件满足, AsyncCall
实例就会在线程池中执行(.start)
,那我们直接去看run()
中的 execute()
:
RealCall.class
@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);
}
}
上面代码中得知, 首先通过层层拦截器链处理生成了response
;然后通过一系列的判断,responseCallback
进行onResponse
与onFailure
回调,最后调用的Dispatcher.finifshed()
这里需要注意的是 这里的Dispatcher.finifshed(this)
与同步中的Dispatcher.finifshed(this)
不一样 参数不同。
Dispatcher.class
/** Used by {@code AsyncCall#run} to signal completion. */
void finished(AsyncCall call) {
finished(runningAsyncCalls, call, true);
}
我们继续看具体的finifshed()
方法:
Dispatcher.class
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!");
if (promoteCalls) promoteCalls();
runningCallsCount = runningCallsCount();
idleCallback = this.idleCallback;
}
if (runningCallsCount == 0 && idleCallback != null) {
idleCallback.run();
}
}
在线程同步的情况下 执行了promoteCalls();
:
Dispatcher.class
private void promoteCalls() {
if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity.
if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote.
for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
AsyncCall call = i.next();
if (runningCallsForHost(call) < maxRequestsPerHost) {
i.remove();
runningAsyncCalls.add(call);
executorService().execute(call);
}
if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.
}
}
经过一系列的判断, 对等待就绪的异步队列进行遍历,生成对应的AsyncCall
实例,并添加到runningAsyncCalls
中,最后放入到线程池中执行!这里就是我们上面说到的等待就绪的异步队列如何与runningAsyncCalls
对接的逻辑。
call
实例realcall
Dispatcher.executed()
中的runningSyncCalls
添加realcall
到此队列中getResponseWithInterceptorChain()
对request
层层拦截,生成Response
Dispatcher.finished()
,把call
实例从队列中移除,返回最终的response
生成一个AsyncCall(responseCallback)
实例(实现了Runnable
)
AsyncCall
实例放入了Dispatcher.enqueue()
中,并判断maxRequests
(最大请求数)maxRequestsPerHost
(最大host
请求数)是否满足条件,如果满足就把AsyncCall
添加到runningAsyncCalls
中,并放入线程池中执行;如果条件不满足,就添加到等待就绪的异步队列,当那些满足的条件的执行时,在Dispatcher.finifshed(this)
中的promoteCalls();
方法中
对等待就绪的异步队列进行遍历,生成对应的AsyncCall
实例,并添加到runningAsyncCalls
中,最后放入到线程池中执行,一直到所有请求都结束。
至此OKhttp
整体流程就分析完了。