Okhttp的调用
分析源码,我们都需要通过调用来查看源码的每一步都做了什么事情。
看下异步调用
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("").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 {
}
});
源码分析。
我们首先看下,OkHttpClient初始化做的事情
public OkHttpClient() {
this(new Builder());
}
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.proxySelector = builder.proxySelector;
...
this.readTimeout = builder.readTimeout;
this.writeTimeout = builder.writeTimeout;
this.pingInterval = builder.pingInterval;
}
...
public Builder() {
dispatcher = new Dispatcher();
...
connectTimeout = 10_000;
readTimeout = 10_000;
writeTimeout = 10_000;
pingInterval = 0;
}
这里我们看到,Okhttp是通过建造者模式初始化的。做的事情,主要是一些常用的配置。
(初始化调度器,缓存策略,连接时间等等)
我们接着看Request的初始化
public final class Request {
final HttpUrl url;
final String method;
final Headers headers;
final RequestBody body;
final Object tag;
Request(Builder builder) {
this.url = builder.url;
this.method = builder.method;
this.headers = builder.headers.build();
this.body = builder.body;
this.tag = builder.tag != null ? builder.tag : this;
}
...
}
我们可以看到,Request里面,主要是通过建造者模式,配置进行网络请求的url,method,header等等内容。
接着看client.newCall(request)
上面做的事情都是配置网络请求的信息。下面,这个调用会执行什么呢。
@Override public Call newCall(Request request) {
return new RealCall(this, request, false /* for web socket */);
}
RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
this.client = client;
this.originalRequest = originalRequest;
this.forWebSocket = forWebSocket;
this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);
}
我们发现这句代码非常简单,就做了一件事。把上面我们构建好的Okhttp,Request传给RealCall。
并初始化它。
最后看下执行call.enqueue(Callback)
我们看下最后是怎么执行的呢
@Override public void enqueue(Callback responseCallback) {
//检查是否已经执行了。
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
//把我们需要监听的返回callback传给AsyncCall,并初始化
//调用我们okhttp创建的dispatcher的enqueue()方法。
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
我们看下AysncCall这个类
final class AsyncCall extends NamedRunnable {
private final Callback responseCallback;
AsyncCall(Callback responseCallback) {
super("OkHttp %s", redactedUrl());
this.responseCallback = responseCallback;
}
它的父类
public abstract class NamedRunnable implements Runnable {
@Override public final void run() {
...
execute();
...
}
protected abstract void execute();
}
我们发现AsyncCall是一个线程,并且父类实现了run()方法,并重新抽象了一个execute()方法,在run()里面调用。让AsyncCall来实现这个execute()方法。
如果调用这个线程的话,AsyncCall的execute()方法就会执行。
再看看 client.dispatcher().enqueue(AsyncCall)
看下这个里面做了什么操作。
public final class Dispatcher {
private int maxRequests = 64;
private int maxRequestsPerHost = 5;
/** Ready async calls in the order they'll be run. */
//这个是准备执行,异步任务的队列
private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();
/** Running asynchronous calls. Includes canceled calls that haven't finished yet. */
//这个是正在执行异步任务的队列
private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();
/** Running synchronous calls. Includes canceled calls that haven't finished yet. */
//这个是正在执行的同步任务的队列
private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();
获取线程池
public synchronized ExecutorService executorService() {
if (executorService == null) {
//核心线程数为9,最大线程数Integer.MAX_VALUE,保留时间60秒
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
}
...
synchronized void enqueue(AsyncCall call) {
//判断正在执行异步任务的队列数量是不是已经达到最大值了
//如果没有到最大值,并且host数量小于5。
//我们就把这个线程放到正在执行的队列里,并执行它
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
//添加
runningAsyncCalls.add(call);
//执行
executorService().execute(call);
} else {
//否则,我们就放到准备执行的异步任务队列里
readyAsyncCalls.add(call);
}
}
}
到这里,我们发现它确实就是一个调度器。
我们假设可以执行。我们看下AsyncCall的execute()方法,都做了什么
AsyncCall的execute()方法
@Override protected void execute() {
boolean signalledCallback = false;
try {
注:1
Response response = getResponseWithInterceptorChain();
//如果没有取消的话,就调用callback的onResponse,否则就调用onFailure。
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 {
//注:2
client.dispatcher().finished(this);
}
}
}
这里,我们先不管注:1和注:2。这就不管成功还是失败,就把数据返回给了我们的callback。
接着,先看下注:2。它是在finally里面执行的。所以执行完后,不管有没有异常,这个方法总会执行的,我们先看下这个。
client.dispatcher().finished(this)
/** Used by {@code AsyncCall#run} to signal completion. */
void finished(AsyncCall call) {
//调用重载方法,第三个参数为true
finished(runningAsyncCalls, call, true);
}
private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
int runningCallsCount;
Runnable idleCallback;
//同步
synchronized (this) {
//这里把我们执行完的call移除了
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();
}
}
···
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();
//如果执行的队列Host不大于最大的host。
//把这个准备的任务,从等待队列移除,放到正在执行的队列,并立即执行。
if (runningCallsForHost(call) < maxRequestsPerHost) {
i.remove();
runningAsyncCalls.add(call);
executorService().execute(call);
}
//直到达到了最大的请求数量,就返回
if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.
}
}
这里,我们就看完了一个任务完成后,做的事情。
1,移除完成的任务
2,判断正在运行的队列,是否还大于最大的请求数。
3,如果大于就返回,如果不大于就从等待的队列里面去取任务并执行,直到达到了,最大的请求数。
现在,我们就差分析,是怎么返回的Response的了。接下来,我们就看下它是怎么执行的。
Response response = getResponseWithInterceptorChain();
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
//把所有的拦截器放到一个集合里
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());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
//初始化一个RealInterceptorChain跟Request,把拦截器都传进去
Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
//调用proceed()方法
return chain.proceed(originalRequest);
}
这里也非常简单,把我们自己设置的拦截器和它自身的,都放到集合里。跟Request一块传给RealInterceptorChain。并调用proceed()方法。
我们再进去看看proceed犯法
RealInterceptorChain.proceed(originalRequest);
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
Connection connection) throws IOException {
if (index >= interceptors.size()) throw new AssertionError();
calls++;
...
// Call the next interceptor in the chain.
//初始化,角标+1,取出interceptor调用intercept方法
RealInterceptorChain next = new RealInterceptorChain(
interceptors, streamAllocation, httpCodec, connection, index + 1, request);
Interceptor interceptor = interceptors.get(index);
//并把下一个RealInterceptorChain穿进去,index+1
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;
}
这里就是创建下一个拦截器。
调用当前拦截器的intercept(next)方法,把下一个拦截器传进去。
- 我们自己的interceptor
- retryAndFollowUpInterceptor
- BridgeInterceptor
- CacheInterceptor
- ConnectInterceptor
- NetworkInterceptors
- 我们自己的networkInterceptors
- CallServerInterceptor
我们看下拦截器是怎么传下去的
RetryAndFollowUpInterceptor.java
@Override public Response intercept(Chain chain) throws IOException {
...
response = ((RealInterceptorChain) chain).proceed(request, streamAllocation, null, null);
...
}
BridgeInterceptor.java
@Override public Response intercept(Chain chain) throws IOException {
Response networkResponse = chain.proceed(requestBuilder.build());
}
...
都是调用下一个构造的chain的proceed方法。
然后,在里面构造下一个chain,执行intercept方法。
* 拦截器的作用:*
- 对当前的request请求做处理(添加/删除头信息等)。
- 调用下一个拦截器。
- 对响应的Response结果,做处理(写入缓存等),并返回给上一个拦截器。
调用完之后,响应Response。整个流程完成。
下一次,看下拦截器都做了什么功能呢。