OkHttp五大拦截器(自己专业整理)

一、什么是OkHttp3

(1)定义:

OkHttp3是一个处理网络请求的开源项目,是目前最火的网络框架,作者是Square公司,
用于代替Android提供的HttpConnection和HttpClient。**

(2)OkHttp的特点

       1、是基于建造者模式(将一个复杂对象的构建与它的表示分离,用于属性参数很多          时。)创建的
建造者模式:https://www.jianshu.com/p/be290ccea05a
      
      2、链式调用,每一个方法的返回值类型都是当前类的对象
      
(3)它的优点是什么

         支持HTTP2/SPDY(SPDY是Google开发的基于TCP的传输层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验。)

         socket自动选择最好路线,并支持自动重连,拥有自动维护的socket连接池,减少握手次数,减少了请求延迟,
共享Socket,减少对服务器的请求次数。


拥有Interceptors轻松处理请求与响应(自动处理GZip压缩)。

二、OKHttp的功能

PUT,DELETE,POST,GET等请求

文件的上传下载

加载图片(内部会图片大小自动压缩)

支持请求回调,直接返回对象、对象集合

支持session的保持

OkHttp请求流程

使用 OkHttp 发起一个请求主要三步:

1、需要构造一个 OkHttpClient

2、构造请求信息 Request

3、发起请求

OkHttpClient client = new OkHttpClient();
                Request request = new Request.Builder().url("http://www.baidu.com")
                        .build();
                try {
                    Response response = client.newCall(request).execute();
                    if (response.isSuccessful()) {
                        System.out.println("成功");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }


发起一个请求整体流程:
首先当OkHttpClient对象想要发送一个网络请求的时会执行newCall()方法这是我们将Request放在这个方法里边,
之后通过返回的okhttp的对象去去调用newCall方法
我们是从newCall开始的在源码中newCall会给我们返回个RealCall,newRealCall();
在RealCall中会将我们传进来的request传给我们的OrigginalRequest对象
(OrigginalRequest之后会在getresponseIntecepterchain里的拦截链RealInterceptorChain()调用)

接下来如果我们是去进行一个同步请求的话也就是在代码当中调用excute()方法
进入excute()方法之后首先会先调用client。dispatcher()。excute(this);
这个方法的目的是通知调节器dispatcher我现在要开始执行任务了然后调用了getresponseInterceptorchain()方法
在这个方法执行结束以后会给我们返回一个通过http请求获取的request对象
最后会调用client。dispatcher。finish()来通知调度器dispatcher我现在任务执行结束了你可以让其他的认为来执行了
然后我们来说说它具体的执行过程,具体的执行过程是·在getresponseInterceptorchain()中执行的
**在这个方法里有一个泛型是interceptor也就是拦截器的集合在这个结合里存入了5个拦截器
之后创建了一个拦截链RealInt**erceptorChain();通过我们拦截链获取的对象去调用process()方法
这个也就是我们所说的链式调用
在这个方法中有一个索引值index每次我们去调用这个process方法的时候他都会加1**
然**后我们会根据这个索引值去判断我们去调用哪个拦截器当我们第一次调用这个方法的时候index为1回去调用我们集合当中
的第一个拦截器当拦截器执行完毕之后会去创建一个新的拦截链并且通过这个新的拦截链去再次调用process方法
然后去执行下一个拦截器
一直到所有的拦截器都调用完毕它会给我们返回一个的Request对象
而这个过程就是一个递归;
那么它是如何去判断我们已经调用到最后一个拦截器了那?
它是通过索引值index当index>集合的长度的时候那么它就会结束这个方法了因为我们index是从1开始的
所以需要index值大于集合长度的时候
我们集合里的拦截器才会全部执行完毕
然后我们去说一说这5个拦截器都是什么分别有什么作用

                                            (五大拦截器)
一、RetryAndFollowUpInterceptor (重定向拦截器)

       RetryAndFollowUpInterceptor 的拦截操作中做了这么几件事:

      1、创建一个 StreamAllocation

      2、发起请求

      3、请求异常时会重试

      4、根据响应码做重定向和重试

      5、重定向时如果地址不一致会释放连接

      6、另外也保存是否取消的状态值,在重试、请求得到响应后都会判断是否取消

二、BridgeInterceptor (桥接拦截器)

       内置的拦截器中第二个是 BridgeInterceptor。Bridge,桥,什么桥?连接用户请求信息 和 HTTP 请求的桥梁。

       BridgeInterceptor 负责把用户构造的请求转换为发送到服务器的请求、把服务器返回的响应转换为用户友好的响应。

      我们说下侨界拦截器大概都做了什么吧,请求前:

             1、如果这个请求有请求体,就添加 Content-Type, Content-Length 等

             2、如果这个请求没有 Host,就通过 url 来获取 Host 值添加到 Header 中

             3、如果这个请求没有接收的数据类型Accept-Encoding,且没指定接收的数据范围,就添加默认接受格式为 gzip

            5、去 CookieJar 中根据 url 查询 Cookie 添加到 Header

            6、如果当前没有,就添加 User-Agent 信息

发起请求后:

           7、解析响应 Header 中的 Cookie

           8、如果想要数据的格式是 gzip,就创建 GzipSource 进行解压,同时移除 Content-Encoding 和 Content-Length

三、CacheInterceptor (缓存拦截器)

        第三个拦截器是缓存处理拦截器 CacheInterceptor,它的重要性用一句话来描述:最快的请求就是不请求,直接用缓存。
       首先,根据request来判断cache中是否有缓存的response,如果有,得到这个response,然后进行判断当前response是否有效,
没有将cacheCandate赋值为空。
根据request判断缓存的策略,是否要使用了网络,缓存 或两者都使用
调用下一个拦截器,决定从网络上来得到response
如果本地已经存在cacheResponse,那么让它和网络得到的networkResponse做比较,决定是否来更新缓存的cacheResponse
缓存未经缓存过的response

四、ConnectInterceptor (连接拦截器)

        我们知道,TCP 协议需要需要建立连接才能进行通信,每次请求都建立连接会极大地影响通信效率。

       OkHttp 的优点之一优化了连接的建立:内部维护了可以重复使用的 Socket 连接池,减少握手次数,加快请求响应。

               1、连接 RealConnection 是对 Socket 的封装

               2、OkHttp 的连接复用主要是通过 StreamAllocation 来实现的,每个连接上持有一个。

               3、StreamAllocation 引用的列表,以此来标识当前连接是否空闲

               4、判断连接是否可以重用,除了比较连接当前的 host,也可以比较路由信息

               5、连接池在添加新连接时会运行清理任务,默认最多空闲连接为 5,最长空闲时间为 5 分钟

五、CallServerInterceptor(读写拦截器)

        最后一个拦截器,CallServerInterceptor,它负责实现网络 IO,所有拦截器都要依赖它才能拿到响应数据。

        1、CallServerInterceptor 首先会将请求中的 header 写给服务器

       2、如果有请求体的话,会再将 body 发送给服务器

       3、最后通过httpCodec.finishRequest() 结束 http 请求的发送

      4、然后从连接中读取服务器的响应,并构造 Response

      5、如果请求的 header或服务器响应的 header 中,Connection 的值为 close,就关闭连接

      6、最后返回 Response


然后说一说异步请求:

        同步中我们调用完newCall方法之后会去调用excute()方法;
而异步中我们回去调用enqueue()方法;
并且调用这个异步方法会实现Call接口,在源码里边,RealCall是Call接口的实现类
,也就是说获取这个异步任务的是ReallCall,ReallCall会把这个异步任务交给他的内部类AcycCall  
AcyCall是NamedRunnable的实现类,NamedRunnable实现了Runnanle接口,通俗易懂省的说AcyCall是一个子线程,
在AcynCall这个类里边有一个enqueye()的方法  ,这时AcynCall 又将任务交给dispatcher去执行入队操作,
而且这里还有一个getResponsewithIntertorchan()这个方法是真正拿到响应并且通过接口回调返回给OkHttpClient对象()

Dispatcher这个类是异步任务调度器,在这个类里边有一个不限制线程数量的一个线程池,
也就是说 dispatcher在线程池里边开启了一个子线程去执行这个异步任务并进行处理,
处理完毕后他会把处理完的数据交给getResponsewithIntertorchan()    
而在getResponseWithInterceptorChain() 方法里会通过链式调用拿到请求结果Resquest这个跟同步方法里是一样的

https://www.jianshu.com/p/b6d139ee971e

你可能感兴趣的:(OkHttp五大拦截器(自己专业整理))