okhttp源码解析系列文章:
第一篇:《okhttp框架简单介绍》
https://blog.csdn.net/colinandroid/article/details/79774907
第二篇:《同步请求流程和源码分析》
https://blog.csdn.net/colinandroid/article/details/79774918
第三篇:《异步请求流程和源码分析》
https://blog.csdn.net/colinandroid/article/details/79774932
第四篇:《任务调度核心类dispatcher解析》
https://blog.csdn.net/colinandroid/article/details/79774936
第五篇:《拦截器流程和源码解析》
https://blog.csdn.net/colinandroid/article/details/79706161

拦截器是okhttp中非常重要的概念,我们来看下okhttp官网是如何描述其拦截器功能的。

它可以实现网络监听、请求以及相应重写、请求失败重试等功能。

我们来看看拦截器是如何工作的。
####1. 还记得getReponseWithInterceptorChain()方法吗?我来看下其内部实现。
【Android okhttp源码解析 五】拦截器流程和源码解析_第1张图片
我们把原始请求originalRequest交给拦截器链chain,这个拦截器链就添加了okhttp提供给我们的各种拦截器。
####2. 拦截器链工作原理
在发起请求前对request进行处理,接着调用下一个拦截器,对response进行处理,返回给上一个拦截器。
####3. 下图就是okhttp提供的几种拦截器,我们逐个介绍
【Android okhttp源码解析 五】拦截器流程和源码解析_第2张图片
####(1)RetryAndFollowUpInterceptor
这是重试和失败重定向拦截器,它的主要作用就是失败重连的。这里需要注意的是:并不是所有网络请求失败都需要重连的,它是有一定限制范围的。okhttp会根据响应异常和响应码,判断是否需要重连。我们来看其intercept()方法。
这里写图片描述
我们看到这里创建了一个StreamAllocation对象,这个对象是初始化了建立http网络请求所需要的组件。这个StreamAllocation对象虽然是在RetryAndFollowUpInterceptor拦截器中创建的,但是它并没有在这个拦截器中使用到,它是在ConnectIntercept中被使用到。它主要就是用于获取(a)连接服务端的connection和(b)用于与服务端数据传输的输入输出流
所有的拦截器都执行完了后,我们才能得到一个网络请求的response。但是网络本来就是不稳定的,在执行过程中肯定会出现不同程度的问题,比如,连接中断了,握手失败了都是由可能的。这个时候response返回码就不是正常的200了,这个response就不一定是可以用的了。那么RetryAndFollowUpInterceptor是如何帮我们拦截的呢?它所有的逻辑都在后面的while循环中,这一整块逻辑这里就不详细讲了,我主要介绍一下以下这个逻辑
这里写图片描述
在重试次数超过了一定限制,就不继续重试了,会把StreamAllocation对象释放调。这里MAX_FOLLOW_UPS默认设置成了20次,也就是最多只失败重连20次。
我们这里简单总结一下
#####1. 创建StreamAllocation对象
#####2. 调用RealInterceptChain.proceed(…)进行网络请求
#####3. 根据异常结果或响应结果判断是否要进行重新请求

####(2)BridgeInterceptor
这是桥接和适配拦截器。这主要就是补充http请求的请求头,如编码方式、内容长度、压缩方式等。
【Android okhttp源码解析 五】拦截器流程和源码解析_第3张图片
从图中可以看出,主要就是加了一些默认的请求头。
这里写图片描述
这里设置了keep-alive,这是实现连接复用的基础。可以看到,okhttp默认就是keep-alive的。当我们开启了一个tcp连接之后,它不会关闭它的连接,而是在一定时间内保持它的连接状态
这里写图片描述
这主要就是将服务端返回的response转化为客户端能使用的response,比如服务端返回的响应若是经过gzip压缩的,那这里就可以进行解压。
这里我们总结一下
#####1. 将用户构建的Request请求转化为能够进行网络访问的请求
#####2. 将处理过的Request进行网络请求
#####3. 将服务端的相应Response转化为可用的Response

####(3)CacheInterceptor
这是缓存拦截器,提供了okhttp的缓存策略,让客户端下一次请求网络的时候节省更多的时间,就可以更快地展示数据。
我们先来看下如何使用缓存功能
这里写图片描述
okhttp为我们封装的很好,只要在创建okhttpclient时配置Cache类就可以。这个Cache类有两个参数:一个是缓存路径,一个是缓存大小。接下来我们来看下这个Cache类如何实现的
#####Cache类的put()方法
可以看到在put方法中有这样一行代码
【Android okhttp源码解析 五】拦截器流程和源码解析_第4张图片
我们知道okhttp其实使用DiskLruCache来实现缓存策略,并且其内部维护了一个清理线程池,来定时清理缓存。接下来我们来看put方法的具体实现
【Android okhttp源码解析 五】拦截器流程和源码解析_第5张图片
这里把response包装成了Entry对象,我们来看下Entry类的组成
【Android okhttp源码解析 五】拦截器流程和源码解析_第6张图片
我们发现它里面包含了url、头部、方法、协议、code、message。
在创建好了Entry后,我们看到它又创建了DiskLruCache.Editor对象,然后调用了edit()方法,并传入了一个key值。这里是将url进行md5加密后作为key
这里写图片描述
接着调用entry的writeTo()方法写进缓存。
【Android okhttp源码解析 五】拦截器流程和源码解析_第7张图片
#####Cache类的get()方法
它用来从缓存中读取响应体
【Android okhttp源码解析 五】拦截器流程和源码解析_第8张图片

####(4) ConnectInterceptor
这是连接拦截器。
【Android okhttp源码解析 五】拦截器流程和源码解析_第9张图片

####(5)CallServerInterceptor
负责将我们的http请求写进网络io中,并且从网络io中读取服务端返回的数据。
【Android okhttp源码解析 五】拦截器流程和源码解析_第10张图片

更多相关文章

  1. android Button源码分析
  2. Ubuntu 16.04环境下使用Clion 2019.1.4 gdb调试Android 7.1.2源
  3. Android分享图片
  4. android JNI处理图片的例子
  5. Android仿微信朋友圈发图片和文字
  6. Android根据电量变化为不同图片的方法【电池电量提示】
  7. Android 图片旋转(使用Matrix.setRotate方法)
  8. Glide的with()方法和生命周期的源码分析

随机推荐

  1. 初学Android,图形图像之在指定点(坐标)播
  2. android MMI(多媒体)接口--音乐播放器
  3. How to set up a link betwteen a real A
  4. Android 以友好的方式显示时间
  5. Android 实现再按一次后退键退出应用程序
  6. Android安装APK时出现Local path doesn't
  7. Android中http交互是用HttpUrlConnection
  8. android activity 相互传值
  9. android 控件 3d 旋转效果
  10. Android 创建桌面快捷键