• 吊打面试官——史上最详细【OkHttp】二


    简介:大三学生党一枚!主攻Android开发,对于Web和后端均有了解。

    个人语录取乎其上,得乎其中,取乎其中,得乎其下,以顶级态度写好一篇的博客。

    上一篇给男朋友介绍了Okhttp的基础知识,OkHttpClient,Request,Call,RealCall以及同步执行和异步执行的源码解释。从这篇博客开始,会给男朋友深入分析拦截器链!拦截器链是OkHttp的一个核心内容,非常非常重要,问到OkHttp不可能不问拦截器链!我们先简介一下拦截器的思想,然后再对每一个拦截器做详细的介绍!

    一.拦截器的分类

    这里仅介绍系统提供的几种拦截器,其实在官方的介绍中,拦截器的流程如图:


    在这里插入图片描述


    拦截器的流程:当一个请求被执行时,系统会执行 Application Intercepter,可以理解为用户自定义的拦截器,然后执行Okhttp的核心拦截器链,经过一系列拦截器的加工和判断最终才会进行网络请求!
    下面先简单介绍每一种拦截器的功能,后面会开辟专门的章节讲解每一个拦截器的源码!

    1.1 retryAndFollowUpInterceptor

    重试和重定向拦截器:该拦截器是拦截器链的第一个,它的作用就和它的名称一样,当我们访问某个服务出现某种异常时,比如该网站需要身份验证,又或者需要进行重定向,这些异常最后会返回到重定向拦截器这里被拦截,他可以对原始请求进行一些操作后自动进行重连尝试。列举几种情况:

    • 需要验证:为原始的Request添加身份验证信息后,自动重新连接
    • 重定向:原有网站不能提供服务,需要跳转到新的一个端口或者服务,那么将原始请求的URL更改为重定向指向的URL,自动重新连接。

    Question:是不是所有失败的情况都会重新连接?
    并不是,只对某些异常做重新连接的尝试!它的优点在于,对于某些不严重的异常或者并不是错误引起的请求错误自动进行重试!!!

    1.2 BridgeInterceptor

    关于BridgeInterceptor的作用,官方的描述是这样的

    Bridges from application code to network code.
    First it builds a network request from a user
    request. Then it proceeds to call the network. 
    Finally it builds a user response from the network response.
    

    英文好的盆友肯定理解了,BridgeInterceptor拦截器的作用就是把用户的Resquest转换成符合网络规范的Request,当服务器返回Response时,又将复合网络规范的Response转换成用户的Response,这样的好处是什么?我们使用起来更方便了,不需要自己去定义请求头的一些格式,也无需要关心返回Response的解压,把精力投放在业务需要上即可!

    1.3 CacheInterceptor

    缓存拦截器的作用,官方解释

    Serves requests from the cacheand writes responses to the cache
    

    简而言之,如果该请求之前已经执行过,并且Response被缓存了,如果经过判断,该缓存可用,就不需要再继续下面的拦截器请求了,直接返回该Response,节省了网络请求的时间,加快速度。能够被缓存的请求的请求方法一定是GET,其他的请求方法都不会被缓存。CacheInterceptor的作用其很简单,但是内部的源码比较复杂,都会开辟专门章节进行讲解!

    1.4 ConnectInterceptor

    官方描述的作用

    Opens a connection to the target serverand proceeds to the next interceptor.
    

    就是开启一个和目标服务器的连接,然后就执行后面的CallServerInterceptor拦截器了,其实更像是为后面的拦截器做铺垫,创建好一条Connection!当然它的连接是如何创建的呢?后面会有介绍。

    1.5 CallServerInterceptor

    This is the last interceptor in the chain. It makes a network call to the server.
    

    他是最后一个拦截器,它的作用就是通过创建好的链接,将Request写入网络的IO流中,并从IO流中读取返回的Response

    二.拦截器的原理

    上面简单的介绍了几种拦截器的作用,但是Okhttp是怎么实现拦截器链的呢?链是怎么形成的呢?还是得回到源代码中寻找答案!

    首先看看RealCall中的getResponseWithInterceptorChain()方法

    ResponsegetResponseWithInterceptorChain() throws IOException {
            // Build a full stack of interceptors.
            //构建了一个拦截器的链表,并将默认的五种拦截器添加进列表
            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 (!forWebSocket) {
                interceptors.addAll(client.networkInterceptors());
            }
            interceptors.add(new CallServerInterceptor(forWebSocket));
              //通过链表构建拦截器链Interceptro.Chain
            Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
                    originalRequest, this, eventListener, client.connectTimeoutMillis(),
                    client.readTimeoutMillis(), client.writeTimeoutMillis());
             //最后调用了拦截器链的proceed()方法
            return chain.proceed(originalRequest);
        }
    

    再来看看preceed()方法做了什么吧!

    // Call the next interceptor in the chain.这里重新构建了一个拦截器链,但是index+1。
        RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,
            connection, index + 1, request, call, eventListener, connectTimeout, readTimeout,
            writeTimeout);
        Interceptor interceptor = interceptors.get(index);//index==0,所以取出第一个
        Response response = interceptor.intercept(next);//执行第一个拦截器。然后以后继续执行下一个拦截器得到Response,只有执行到最后一个拦截器才会得到Response,返回给最初的调用者。这也就是拦截器链的实现原理
    

    三.总结

    本篇简单的介绍了几种拦截器的作用,并介绍了拦截器的原理。后面我们会详细介绍每一种拦截器的源代码!!!男朋友听完都说好!!!

    先别走,我有一个资源学习群要推荐给你,它是白嫖党的乐园,小白的天堂!

    相关阅读:

    抖音黄v

    抖音1w赞多少钱

    抖音和哔哩哔哩

  • 相关阅读:
    macOS下查看端口是否被占用命令
    macOS下安装tomcat服务器
    unittest 知识问答题-也许面试会有用-欢迎补充
    python.unittest中常用断言方法
    如何在命令行terminal中运行pycharm项目
    如何保证 软件测试覆盖率
    如何衡量 测试覆盖率
    软件测试全流程 总结
    接口测试对传统测试模型的改进
    关于http/https协议
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13309133.html
Copyright © 2020-2023  润新知