美文网首页框架【库】Android收藏集芳草集
手把手讲解 OkHttp硬核知识点(2)

手把手讲解 OkHttp硬核知识点(2)

作者: 波澜步惊 | 来源:发表于2019-08-15 14:29 被阅读17次

    前言

    手把手讲解系列文章,是我写给各位看官,也是写给我自己的。
    文章可能过分详细,但是这是为了帮助到尽量多的人,毕竟工作5,6年,不能老吸血,也到了回馈开源的时候.
    这个系列的文章:
    1、用通俗易懂的讲解方式,讲解一门技术的实用价值
    2、详细书写源码的追踪,源码截图,绘制类的结构图,尽量详细地解释原理的探索过程
    3、提供Github 的 可运行的Demo工程,但是我所提供代码,更多是提供思路,抛砖引玉,请酌情cv
    4、集合整理原理探索过程中的一些坑,或者demo的运行过程中的注意事项
    5、用gif图,最直观地展示demo运行效果

    如果觉得细节太细,直接跳过看结论即可。
    本人能力有限,如若发现描述不当之处,欢迎留言批评指正。

    学到老活到老,路漫漫其修远兮。与众君共勉 !


    引子

    OkHttp 知名第三方网络框架SDK,使用简单,性能优秀,但是内核并不简单,此系列文章,专挑硬核知识点详细讲解. 何为硬核,就是要想深入研究,你绝对绕不过去的知识点

    本文接上一篇文章: https://www.jianshu.com/p/dc06a54e920a
    详细讲解 OKHttp的核心内容,拦截器。不过拦截器众多,有系统自带的,也有我们可以自己去自定义的。

    image.png

    这是网络请求执行的核心方法的起点,这里涉及了众多拦截器,

    正文大纲

    系统自带拦截器

    1 重试与重定向拦截器 RetryAndFollowUpInterceptor
    2 桥接拦截器 BridgeInterceptor
    3 缓存拦截器 CacheInterceptor
    4 连接拦截器 ConnectInterceptor
    5 服务调用拦截器 CallServerInterceptor

    可自定义的拦截器

    • 继承Intercetor
    • 继承NetworkInterceptor

    正文

    在详解拦截器之前,有必要先将 RealCallgetResponseWithInterceptorChain() 方法最后两行展开说明:

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

    这里最终返回 一个Response,进入chain.proceed方法,最终索引到 RealInterceptorChainproceed方法:

    image.png
    之后,我们追踪这个interceptor.intercept(next); ,发现是一个接口,找到实现类,有多个,进入其中的RetryAndFollowUpInterceptor,发现:
    image.png
    它这里又执行了 chain.proceed,于是又回到了RealInterceptorChain.proceed()方法,但是此时,刚才链条中的拦截器已经不再是原来的拦截器了,而是变成了第二个,因为每一次都index+1了(这里比较绕,类似递归,需要反复仔细体会),依次类推,直到所有拦截器的intercept方法都执行完毕,直到链条中没有拦截器。就返回最后的Response

    这一段是okhttp责任链模式的核心,应该好理解。

    系统自带拦截器

    1. 重试与重定向拦截器 RetryAndFollowUpInterceptor

    先说结论吧:

    顾名思义,retry 重试, FollowUp 重定向 。这个拦截器处在所有拦截器的第一个,它是用来判定要不要对当前请求进行重试和重定向的,那么我们应该关心的是:什么时候重试什么时候重定向

    先来关注一下RetryAndFollowUpInterceptor的核心方法 interceptor() :

    @Override public Response intercept(Chain chain) throws IOException {
        ...省略
        while (true) {
          ...省略
          try {
            response = ((RealInterceptorChain) chain).proceed(request, streamAllocation, null, null);
            releaseConnection = false;
          } catch (RouteException e) {
            // The attempt to connect via a route failed. The request will not have been sent.
            if (!recover(e.getLastConnectException(), false, request)) {
              throw e.getLastConnectException();
            }
            releaseConnection = false;
            continue;
          } catch (IOException e) {
            // An attempt to communicate with a server failed. The request may have been sent.
            boolean requestSendStarted = !(e instanceof ConnectionShutdownException);
            if (!recover(e, requestSendStarted, request)) throw e;
            releaseConnection = false;
            continue;
          }
          ...省略
          if (followUp == null) {
            if (!forWebSocket) {
              streamAllocation.release();
            }
            return response;
          }
          ...省略
    
        }
      }
    
    

    上面的代码中,我只保留了关键部分。其中有两个continue,一个return.

    当请求到达了这个拦截器,它会进入一个while(true)循环,当发生了RouteException 异常(这是由于请求尚未发出去,路由异常,连接未成功),就会去判断recover方法的返回值,根据返回值决定要不要continue.
    当发生IOException(请求已经发出去,但是和服务器通信失败了)之后,同样去判断recover方法的返回值,根据返回值决定要不要continue.
    recover()方法内部:

    如果这两个continue都没有执行,就有可能走到最后的return response结束本次请求.


    2. 桥接拦截器 BridgeInterceptor


    3. 缓存拦截器 CacheInterceptor


    4. 连接拦截器 ConnectInterceptor


    5. 服务调用拦截器 CallServerInterceptor


    可自定义的拦截器

    继承Intercetor


    继承NetworkInterceptor


    结语


    相关文章

      网友评论

        本文标题:手把手讲解 OkHttp硬核知识点(2)

        本文链接:https://www.haomeiwen.com/subject/hxlzjctx.html