okhttp以其卓越的网络处理性能,而被广泛的使用。作为一个新手的我,当然也得熟悉下。以下内容如有问题请及时指正
一, OkHttp重要组成部分
OkHttpClient: 作为OkHttp使用的核心组件,入口。 其包含请求分发, 响应拦截, 网络配置(超时,重定向重试)等等 。
OkHttpClient可通过OkHttpClient.Builder创建。
Call: 请求调用的抽象接口,支持同步和异步请求。同步调用:execute , 异步调用:enqueue。 支持cancel。
需依赖request
(实际我们用的是RealCall)
Request: 承载网络请求信息, 包含 头部headers, method:GET/POST等 , 请求地址, requestBody(Post时报文体)。
Request: 承载网络请求信息, 包含 头部headers, method:GET/POST等 , 请求地址, requestBody(Post时报文体)。
通过request.Buider去创建。
Response: 请求回应(包含body, request,同时包含缓存回应, 网络回应, 重试回应等等状态记录)
Response: 请求回应(包含body, request,同时包含缓存回应, 网络回应, 重试回应等等状态记录)
目前同步请求可以直接返回response,异步请求回调接口中也会返回response。
Dispatcher: 请求分发, 主要为同步分发,异步分发(同步则当前线程中阻塞式调用, 异步则是开启线程池去调用请求)
Dispatcher: 请求分发, 主要为同步分发,异步分发(同步则当前线程中阻塞式调用, 异步则是开启线程池去调用请求)
维护异步分发队列, 当前执行中同步队列, 以及带执行异步队列。
Interceptor: 拦截器(重要), 实际请求处理相应逻辑都是由拦截器完成。我们在okHttpClient中可以自定义拦截器,目前okHttp请求中用到的拦截器如下:
Interceptor: 拦截器(重要), 实际请求处理相应逻辑都是由拦截器完成。我们在okHttpClient中可以自定义拦截器,目前okHttp请求中用到的拦截器如下:
RetryAndFlowUpInterceptor: 错误重试或者重定向处理
BridgeInterceptor: 桥接拦截器(支持gzip格式传输等)
CacheInterceptor: 缓存拦截器 (支持从缓存中读取数据)
ConnectInterceptor: 连接拦截器 (创建socket连接通信)
BridgeInterceptor: 桥接拦截器(支持gzip格式传输等)
CacheInterceptor: 缓存拦截器 (支持从缓存中读取数据)
ConnectInterceptor: 连接拦截器 (创建socket连接通信)
CallServerInterceptor: 服务拦截器 (跟远端服务通信,拿到网络请求响应)
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 (!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中添加拦截器是会预先处理。
拦截器执行结果会传递到上个拦截器,线性串联。
补充:针对具体业务场景的时候,有时候需要定义错误重试,请求日志等等,我们可以定义不同拦截器进行处理,由于拦截器是线性处理的,错误重试,请求日志按道理应该在前面处理,而基于这种考量,这也是为什么okhttpclient中添加拦截器是会预先处理。