okhttp以其卓越的网络处理性能,而被广泛的使用。作为一个新手的我,当然也得熟悉下。以下内容如有问题请及时指正
一, OkHttp重要组成部分
OkHttpClient:作为OkHttp使用的核心组件,入口。 其包含请求分发, 响应拦截, 网络配置(超时,重定向重试)等等 。
OkHttpClient可通过OkHttpClient.Builder创建。
Call:请求调用的抽象接口,支持同步和异步请求。同步调用:execute ,异步调用:enqueue。支持cancel。
需依赖request
(实际我们用的是RealCall)
Request:承载网络请求信息, 包含 头部headers, method:GET/POST等 , 请求地址,requestBody(Post时报文体)。 通过request.Buider去创建。
Response: 请求回应(包含body, request,同时包含缓存回应, 网络回应, 重试回应等等状态记录) 目前同步请求可以直接返回response,异步请求回调接口中也会返回response。
Dispatcher: 请求分发, 主要为同步分发,异步分发(同步则当前线程中阻塞式调用, 异步则是开启线程池去调用请求) 维护异步分发队列, 当前执行中同步队列, 以及带执行异步队列。
Interceptor: 拦截器(重要), 实际请求处理相应逻辑都是由拦截器完成。我们在okHttpClient中可以自定义拦截器,目前okHttp请求中用到的拦截器如下: RetryAndFlowUpInterceptor:错误重试或者重定向处理
BridgeInterceptor:桥接拦截器(支持gzip格式传输等)
CacheInterceptor:缓存拦截器(支持从缓存中读取数据)
ConnectInterceptor:连接拦截器(创建socket连接通信) CallServerInterceptor:服务拦截器(跟远端服务通信,拿到网络请求响应)
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()));
Chain:上面我们看到拦截器,okHttp内部具有多个拦截器,而且拦截器的业务定义是依赖线性调用的,因此就需要用到Chain来执行,实际RealInterceptorChain
Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
按业务顺序执行interceptor,而且每个interceptor最多只会调用一次。chain执行调用逻辑 chain.Proceed()会按顺序执行拦截器。
二, OkHttp执行流程
文章图片
由上执行流程图: (1) okHttpClient入口调用newCall(实际创建RealCall),需要依赖Request信息 (2) Call.execute同步执行,阻塞当前线程,直接返回response。 call.enqueue异步执行,在回调中返回Response。 (3) Call实际依赖Dispatcher分发执行,同步则直接执行,异步则创建线程池执行(实际业务执行逻辑在RealCall) (4) RealCall实际调用getResponseWithInterceptorChain处理当次业务请求(创建Chain以及interceptors用于流线型业务处理) (5)Chain执行proceed,用于顺序执行已注册的拦截器interceptors。 (6)RetryAndFollowUpInterceptor处理 重定向重试。 (7)BridgeInterceptor 用于优化header请求头,判断是否有必要进行gzip数据传输。 (8)CacheInterceptor 用于通过缓存读取数据内容,判断是否要进一步进行网络数据获取并最终同步缓存。 (9)ConnectInterceptor 创建Socket链接,同时会有连接池缓存链接 (10)CallServerInterceptor 拿到上面的连接,进行网络数据获取。
拦截器执行结果会传递到上个拦截器,线性串联。
补充:针对具体业务场景的时候,有时候需要定义错误重试,请求日志等等,我们可以定义不同拦截器进行处理,由于拦截器是线性处理的,错误重试,请求日志按道理应该在前面处理,而基于这种考量,这也是为什么okhttpclient中添加拦截器是会预先处理。
以上为请求流程的介绍,如有问题请各位大神帮忙指正!
【okhttp|浅析OkHttp使用-请求分发流程】