OkHttp3源码(八) ------ RealCall

RealCall类 —–前面我们讲的是HTTP相关的概念在OKhttp3中是如何通过类实现的 。 Okhttp的请求过程是先组装请求报文,然后将请求报文封装成一个任务,最后交由“网络”去执行这个任务。 而RealCall就是这个任务

我们看一下源码。

1、RealCall属性

//重连接拦接器 ------ 拦截器我们会在后面的章节讲解
final RetryAndFollowUpInterceptor retryAndFollowUpInterceptor;
//客户端
final OkHttpClient client;
//请求报文
final Request originalRequest;
//任务是否被执行
private boolean executed;

属性还是挺少的,虽然少,但是每个属性都至关重要。

2、构造方法

 RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    this.client = client;
    this.originalRequest = originalRequest;
    this.forWebSocket = forWebSocket;
    this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);
  }

构造函数主要完成属性的初始化。

3、一般方法

//获得请求报文
@Override public Request request() {
return originalRequest;
}
//获得连接流 ------ 一个连接上可以对应多个流
StreamAllocation streamAllocation() {
return retryAndFollowUpInterceptor.streamAllocation();
}
//取消这个任务,不再执行。
@Override public void cancel() {
retryAndFollowUpInterceptor.cancel(); //内部调用的是streamAllocation.cancel()。
}
//这个任务是否被执行
@Override public synchronized boolean isExecuted() {
return executed;
}
//这个任务是否被取消执行
@Override public boolean isCanceled() {
return retryAndFollowUpInterceptor.isCanceled();
}
//根据当前任务的的用户client和请求报文实例化新的任务
@Override public RealCall clone() {
return new RealCall(client, originalRequest, forWebSocket);
}

4、AsyncCall类

final class AsyncCall extends NamedRunnable {
private final Callback responseCallback;

AsyncCall(Callback responseCallback) {
super("OkHttp %s", redactedUrl());
this.responseCallback = responseCallback;
}

@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);
}
}
}

//AsyncCall类是RealCall的内部类
//AsyncCall继承NameRunnable
//NameRunnable是一个可以指定线程名称线程执行体。
//在线程池中调用NameRunnable的run()方法
//run()方法调用execute()方法
//通过AsyncCall持有的Callback对象实现回调
//注意这一过程是运行在子线程中的

5、主要方法

//同步执行这个任务------不会使用线程池
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
try {
client.dispatcher().executed(this);
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} finally {
client.dispatcher().finished(this);
}
}

//异步执行这个任务 ------ 会使用线程池
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}

对于这两个执行方法的区别就是线程池的是否使用
其中方法体里面重要的三句代码分别为
1、通过Dispatcher类来维护任务(任务动态的增加和删除),实现任务的高并发 处理。可以把Dispatcher理解为一个任务栈。
client.dispatcher().enqueue(new AsyncCall(responseCallback)); —— 异步执行的
client.dispatcher().executed(this);—— 同步执行的
2、当任务执行完,将任务从任务栈中删除。
client.dispatcher().finished(this);
3、通过层层拦截器执行任务。
Response result = getResponseWithInterceptorChain();

扫描二维码关注公众号,回复: 2612598 查看本文章

6、真正的网络请求和响应过程

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());
}
interceptors.add(new CallServerInterceptor(forWebSocket));

Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);
}
}

开始通过层层拦截器执行任务
通过这个方法可以知道,我们设置的普通拦截器要优先于我们设置的网络拦截器被执行。
拦截器的执行先后 普通拦截器>RetryAndFollowUpInterceptor>BridgeInterceptor
.>CacheInterceptor>ConnectInterceptor>networkInterceptors>CallServerInterceptor
对于拦截器的具体实现我们后面会讲。

猜你喜欢

转载自blog.csdn.net/look_Future/article/details/79731954