先看RealCall
发送一个请求,我们会先创建一个request,然后使用okHttpClient.newCall(request),创建一个call进行网络请求,这个call,就是RealCall
 
RealCall中有一个重要的方法:execute(),同步执行网络请求,这个方法用request请求网络,返回response
 

红色方框内就是核心方法,组成拦截链,把这个请求通过拦截链处理之后,才会真正的去请求网络,获取response。

这个方法里添加了一系列的拦截器,看第一个红框,首先是把Application Interceptor添加进去了,然后依次添加了RetryAndrFollowUpInterceptor,BridgeInterceptor,CacheInterceptor,ConnectInterceptor,之后又在第二个红框的位置添加了networkInterceptor,最终的拦截器是CallServerInterceptor,记住,这个顺序对后面是有影响的!
 
先了解一下Interceptor
看一下OkHttp官网上的一张图

这张图看起来有点烦人,专治各种颈椎病。
从这张图上,我们看到拦截器分两种,一种是Application Interceptors,一种是Network Interceptors,有什么区别呢?先看一下官网怎么说的

归根结底,这两种拦截器是因为位置不一样导致他们有很大的区别的,我们从拦截器列表中看到,Application Interceptors是放在最外层的拦截器,它最先拦截到request,但是response是最后才拦截到的,也就是说,如果下面的retry拦截器进行了重连的操作,Application Interceptors是不知道的,而Network Interceptors相反,最先拦截到resopnse,直到要请求网络的时候,才拦截到request,所有的真正的网络请求,Network Interceptors都可以拦截到。我们看一下灵魂画手画的流程图:

RealCall中的execute()调用了getResponseWithInterceptorChain(),而这个方法在添加了一系列的拦截器之后实例化了一个RealInterceptorChain,并调用了chain.proceed()方法。我们看,上图,Chain持有拦截器列表,并持有一个interceptor,在proceed()方法中,interceptor拦截了request,然后实例化了一个持有下一个拦截器的chain,并调用这个chain的proceed。那么,按照顺序,应该是Application Interceptor 首先拦截了request,然后在持有retry拦截器的chain中调用proceed()方法,retry拦截器拦截request,按照顺序往下走,在network Interceptor 拦截request之后,最终callserver  interceptor去请求了网络。
 
当网络返回response之后,正好反过来,CallServerInterceptor处理之后,先由network interceptor拦截,然后其他的拦截,最后才是Application Interceptor拦截。
 
RealInterceptorChain中的proceed()方法会实例化下一个拦截器的chain。并调用当前拦截器进行拦截操作。
 
 

简单说一个拦截器的使用场景,RetryAndrFollowUpInterceptor会拦截到网络请求的结果和异常,如果有异常,这个拦截器会从request重新请求。这时候,在RetryAndrFollowUpInterceptor之上的Application Interceptor是不会知道retry做了什么,发生了什么,直到retry拦截器把response反馈给Application Interceptor。因为retry拦截器里有个while(true)死循环!!!

OkHttp之Interceptor的更多相关文章

  1. # Okhttp解析—Interceptor详解

    Okhttp解析-Interceptor详解 Interceptor可以说是okhttp的精髓之一,Okhttp重写请求/响应.重试.缓存响应等操作,基本都是在各个Interceptor中完成的,上篇 ...

  2. OkHttp自定义重试次数

    本文主要应用了OkHttp的Interceptor来实现自定义重试次数 虽然OkHttp自带retryOnConnectionFailure(true)方法可以实现重试,但是不支持自定义重试次数,所以 ...

  3. Retrofit/Okhttp API接口加固技术实践(上)

    作者:Tamic 地址:http://blog.csdn.net/sk719887916/article/details/61914609 写这篇文章,我纠结了非常久,究竟是属于app安全系列,还是属 ...

  4. Okhttp 插入缓存拦截器 解析

    我们在做网络请求的时候,如果网络请求过于频繁而且请求的数据变动不大,或者基本没有变动,这个时候如果没有缓存功能,我们想一下 会浪费掉多少资源,一次请求刷新一次,去请求一次,不但会消耗用户的流量,而且还 ...

  5. Android OKHttp 可能你从来没用过的拦截器 【实用推荐】

    前言 在平时开发中,你有没有下面这样的困扰呢? 场景一 明明是服务端的接口数据错误,而QA(测试)第一个找到的可能是客户端开发的你,为什么这个页面出现错误了? 而作为客户端开发的你,可能要拿出测试机连 ...

  6. Android网络框架比较

    今天,公司需要为一个安卓app选择一个合适的网络框架,具体我了解,主要的安卓网络框架有okhttp,retrofit,android-async-http,volley. 查找网上的资料,大致可以得到 ...

  7. Android Weekly Notes Issue #249

    Android Weekly Issue #249 March 19th, 2017 Android Weekly Issue #249 本期内容包括: 一个设计的实现Demo讨论; Kotlin的C ...

  8. OkHttp 3.x 源码解析之Interceptor 拦截器

    拦截器 Java里的拦截器是动态拦截Action调用的对象.它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提 ...

  9. com.squareup.okhttp.Interceptor

    retrift 集成了okhttp,所以,我们以后就不用再单独的引用http的jar 了. 但是,今天遇到一个问题,就是okhttp是这样设置一些intercept的: private static ...

随机推荐

  1. php中的内存管理的介绍(转)

    本篇文章给大家带来的内容是关于php中的内存管理的介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 一.php内存管理概述——Zend引擎 由于计算机的内存由操作系统进行管理,所以 ...

  2. SQL的修炼

    查询所有区有多少人,从而得知一个区有多少设备. ###############################################select o2.ORG_ENDDATE as name ...

  3. 使用new来分配内存

    对指针的工作方式有一定的了解之后,来看看他如何实现在程序运行时分配内存.前面我们都将指针初始化为变量的地址(int * pt; pt = & a):变量是在编译时分配的有名称的内存,而指针只是 ...

  4. 51单片机---点亮一个LED灯

    1 程序源码 #include <REGX52.H> `包含51单片机的头文件` sbit led = P0^0; int main(void) { while(1) { led = 1; ...

  5. Jdbc来操作事物 完成模拟银行的转账业务

    创建JDBC工具类 package cn.aa4_2.JDBCUtils; import java.io.FileReader; import java.io.IOException; import ...

  6. vue.js组件传值

    组件传值有一下几种方式:父子传值(父传子,子传父),非父子传值,vuex,插槽作用域 1.父子传值: (1)父传子: 传值方:当子元素在父元素中当标签使用时,通过给子标签绑定一个自定义属性,属性值为需 ...

  7. JVM垃圾回收机制之对象回收算法

    前言 在前面的文章中,介绍了JVM内存模型分为:堆区.虚拟机栈.方法区.本地方法区和程序计数器,其中堆区是JVM中最大的一块内存区域,在Java中的所有对象实例都保存在此区域,它能被所有线程共享. 在 ...

  8. JDK新特性之可变个数的形参的方法

    可变个数的形参的方法:1.格式:对于方法的形参来说:数据类型...形参名2.可变个数的形参的方法与同名的方法之间可以构成重载3.可变个数的形参在调用时,个数从0开始,到无穷都可以(在调用这个方法时,s ...

  9. todos+增删改查+js练习

    增删改查+js练习+es6字符串模板@haloBabyBear <!DOCTYPE html> <html lang="en"> <head> ...

  10. 温度转换 II

    描述 温度的刻画有两个不同体系:摄氏度(Celsius)和华氏度(Fabrenheit). 请编写程序将用户输入华氏度转换为摄氏度,或将输入的摄氏度转换为华氏度. 转换算法如下:(C表示摄氏度.F表示 ...