OkHttp3-只会用是不够的,还得懂这些,android系统四层架构

本文详细解析了OkHttp3的同步请求execute()和异步请求enqueue(Callback responseCallback)的执行流程。在同步请求中,重点分析了Dispatcher调度器的角色,包括它如何管理请求队列以及执行拦截器链。异步请求则是通过enqueue方法将任务放入待执行队列,并由Dispatcher进行调度执行。文中还探讨了各个关键方法,如intercept(),以及如何通过ExecutorService执行异步任务。
摘要由CSDN通过智能技术生成
a).同步请求execute()

@Override
public Response execute() throws IOException {
synchronized (this) {
//一个请求只能执行一次
if (executed) throw new IllegalStateException(“Already Executed”);
executed = true;
}
captureCallStackTrace();
timeout.enter();
//http请求调用的生命周期
eventListener.callStart(this);
try {
client.dispatcher().executed(this);//注释1
Response result = getResponseWithInterceptorChain();//注释2
if (result == null) throw new IOException(“Canceled”);
return result;
} catch (IOException e) {
e = timeoutExit(e);
eventListener.callFailed(this, e);
throw e;
} finally {
client.dispatcher().finished(this);
}
}

关键代码为标出来的注释1和注释2两处,先看注释1,看下client.dispatcher()返回的Dispatcher对象:

/**
* Policy on when async requests are executed.
*

Each dispatcher uses an {@link ExecutorService} to run calls internally. If you supply your
* own executor, it should be able to run {@linkplain #getMaxRequests the configured maximum} number
* of calls concurrently.
/public final class Dispatcher {
//最大请求数
private int maxRequests = 64;
//每一个主机的最大请求数
private int maxRequestsPerHost = 5;
private @Nullable Runnable idleCallback;
/
* Executes calls. Created lazily. /
//线程池
private @Nullable ExecutorService executorService;
/
* Ready async calls in the order they’ll be run. /
//准备执行的异步请求队列
private final Deque readyAsyncCalls = new ArrayDeque<>();
/
* Running asynchronous calls. Includes canceled calls that haven’t finished yet. /
//正在执行的异步请求队列
private final Deque runningAsyncCalls = new ArrayDeque<>();
/
* Running synchronous calls. Includes canceled calls that haven’t finished yet. /
//正在执行的同步请求队列
private final Deque runningSyncCalls = new ArrayDeque<>();
public Dispatcher(ExecutorService executorService) {
this.executorService = executorService;
}
void enqueue(AsyncCall call) {
synchronized (this) {
readyAsyncCalls.add(call);
// Mutate the AsyncCall so that it shares the AtomicInteger of an existing running call to
// the same host.
if (!call.get().forWebSocket) {
AsyncCall existingCall = findExistingCallWithHost(call.host());
if (existingCall != null) call.reuseCallsPerHostFrom(existingCall);
}
}
promoteAndExecute();
}
/
* Used by {@code Call#execute} to signal it is in-flight. */
synchronized void executed(RealCall call) {
runningSyncCalls.add(call);
}
//…代码略…
}

这是一个调度器,内部维护着最大请求数,每个主机最大请求数等参数,最重要的是维护着三个队列,分别是“将要执行的异步请求队列”、“正在执行的异步请求队列”和“正在执行的同步执行队列”。之前的代码段中注释1处调用dispatcher.executed(this)方法,我们看到这个方法只是把当前的realCall实例加入到了请求队列中。接下来看注释2处的代码Response result = getResponseWithInterceptorChain(),看下这个方法:

Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
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 (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
//发起请求访问服务器的拦截器
interceptors.add(new CallServerInterceptor(forWebSocket));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值