okHttp如何使用及调用流程源码分析

2019-11-13  本文已影响0人  MadnessXiong

1. okHttp的使用

OkHttpClient okHttpClient = new OkHttpClient();

然后看下配置项:

  final Dispatcher dispatcher;//调度器,线程管理
  final @Nullable Proxy proxy;//代理
  final List<Protocol> protocols;//协议(如Http1.1,Http2)
  final List<ConnectionSpec> connectionSpecs;//传输层版本和连接协议
  final List<Interceptor> interceptors;//拦截器
  final List<Interceptor> networkInterceptors;//网络拦截器
  final EventListener.Factory eventListenerFactory;
  final ProxySelector proxySelector;//代理选择器
  final CookieJar cookieJar;//cookie
  final @Nullable Cache cache;//缓存
  final @Nullable InternalCache internalCache;//内部缓存
  final SocketFactory socketFactory;//socket工厂
  final @Nullable SSLSocketFactory sslSocketFactory;//安全套层socket工厂,用于https
  final @Nullable CertificateChainCleaner certificateChainCleaner;//验证确认响应证书
  final HostnameVerifier hostnameVerifier;//主机名确认
  final CertificatePinner certificatePinner;//用于自签名证书
  final Authenticator proxyAuthenticator;//代理身份验证
  final Authenticator authenticator;//本地身份验证
  final ConnectionPool connectionPool;/连接池
  final Dns dns;//dns
  final boolean followSslRedirects;/安全套接层重定向
  final boolean followRedirects;//本地重定向(http和https互相跳转时,默认为true)
  final boolean retryOnConnectionFailure;//连接失败重试
  final int connectTimeout;//连接超时时间
  final int readTimeout;//读取超时时间
  final int writeTimeout;//写入超时时间
  final int pingInterval;//ping的间隔

其实构建OkHttpClient时okHttp已经帮我们实现了默认配置,我们可以根据需要进行修改。

 OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
        okHttpBuilder.addInterceptor(...);
        okHttpBuilder.cache(...);
        OkHttpClient okHttpClient = okHttpBuilder.build();

2. okHttp的调用流程源码分析

image-20191113010116100.png

先执行第一个Interceptor的前置逻辑,然后执行chain.proceed(),把任务转交给下一个Interceptor,下一个Interceptor同样执行它的前置逻辑,完成后通过chain.proceed()把任务继续传递下去,直到最后一个Interceptor。最后一个Interceptor获取到结果后返回到上一个Interceptor,执行它的后置逻辑,执行完后再返回给上一次,最后返回结果给getResponseWithInterceptorChain()。

总结一下:当我们发起一个请求后,当来到getResponseWithInterceptorChain()时,它添加了一系列Interceptor,构成一个责任链。每一层的Interceptor通过前置逻辑对请求的原始数据(request)进行加工,然后再通过chain.proceed()把任务传递给下一层,当传递到最后一个Interceptor时会返回请求的结果(response),然后再逐层返回,通过每一层的后置逻辑对结果(response)进行处理,最后返回给请求端。

所以我们可以通过添加自定义Interceptor的方式,在请求前通过前置逻辑对请求request进行修改,如添加header等。等返回结果后,通过后置逻辑对返回数据response进行处理。OkHttp通过OkHttpClient.Builder的addInterceptor()和addNetworkInterceptor()支持了添加自定义Interceptor,后面会说到。

3. okHttp调用流程总结

  1. 构建okHttpClient,并添加需要的配置。如添加自定义的Interceptor,是否重连,设置超时时间,Cookie,Cache等。

  2. 配置Request,如请求方法,请求头,请求体等。

  3. 通过okHttpClient.newCall(request)生成Call对象,这个Call实际是RealCall。

  4. 执行它的enqueue(),最后实际会执行到AsyncCall的execute()中,然后执行它的getResponseWithInterceptorChain()等待返回结果。

    在getResponseWithInterceptorChain()中使用了责任链模式,每一个节点是一个interceptor,在哦它的interceptors()中:添加前置逻辑,然后调用proceed方法,传递请求到下一层,等待结果返回,直达最后网络请求完成返回数据,又原路返回执行每一个interceptors的后置逻辑。

  5. getResponseWithInterceptorChain()首先执行了自定义的Interceptor的前置逻辑,它获取了用户设置的自定义配置并添加到请求中,然后转交给下一层,并等待结果返回。

  6. 第二个执行了RetryAndFollowUpInterceptor的前置逻辑,它初始化了连接对象,如果没有取消请求,则继续转交请求给下一层,并等待结果返回。

  7. 第三个执行了BridgeInterceptor的前置逻辑,它处理了header信息,并添加了gzip支持。然后转交请求给下一层,并等待结果返回。

  8. 第四个执行了CacheInterceptor的前置逻辑,它创建了缓存策略,如果可以返回缓存,或网络有问题这直接返回。否则转交请求给下一层,并等待结果返回。

  9. 第五个执行了ConnectInterceptor的前置逻辑,它构建并建立了连接,然后转交请求给下一层,并等待结果返回。

  10. 第五个执行了networkInterceptors的前置逻辑,这里如果设置了,那么可以在请求发出前做最后的处理,然后转交请求给下一层,并等待结果返回。

  11. 第五个执行了CallServerInterceptor的前置逻辑,这是最后一个Interceptor,它已经拿到了客户端设置的请求的所有配置,并且连接已经建立。在这里正式开始往网络写请求,并等待返回请求结果。返回结果进行一定的判断处理后直接返回给上一层。

  12. 如果设置了networkInterceptors,那么结果先在networkInterceptors的后置逻辑处理后再返回给ConnectInterceptor

  13. ConnectInterceptor没有后置逻辑,直接返回给CacheInterceptor

  14. CacheInterceptor的后置逻辑对返回结果进行缓存后,然后返回给BridgeInterceptor

  15. BridgeInterceptor的后置逻辑对返回结果进行解压缩,然后返回给RetryAndFollowUpInterceptor

  16. RetryAndFollowUpInterceptor的后置逻辑对返回结果进行判断,是否需要重定向,是否需要执行重试逻辑,不需要则返回请求结果

  17. 如果设置了自定义Interceptor,那么会返回到这里,根据需求对结果进行处理,然后最终返回给调用端。

上一篇 下一篇

猜你喜欢

热点阅读