【Android okhttp源码解析 五】拦截器流程和源码解析

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()方法吗?我来看下其内部实现。
这里写图片描述
我们把原始请求originalRequest交给拦截器链chain,这个拦截器链就添加了okhttp提供给我们的各种拦截器。
####2. 拦截器链工作原理
在发起请求前对request进行处理,接着调用下一个拦截器,对response进行处理,返回给上一个拦截器。
####3. 下图就是okhttp提供的几种拦截器,我们逐个介绍
这里写图片描述
####(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请求的请求头,如编码方式、内容长度、压缩方式等。
这里写图片描述
从图中可以看出,主要就是加了一些默认的请求头。
这里写图片描述
这里设置了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方法中有这样一行代码
这里写图片描述
我们知道okhttp其实使用DiskLruCache来实现缓存策略,并且其内部维护了一个清理线程池,来定时清理缓存。接下来我们来看put方法的具体实现
这里写图片描述
这里把response包装成了Entry对象,我们来看下Entry类的组成
这里写图片描述
我们发现它里面包含了url、头部、方法、协议、code、message。
在创建好了Entry后,我们看到它又创建了DiskLruCache.Editor对象,然后调用了edit()方法,并传入了一个key值。这里是将url进行md5加密后作为key
这里写图片描述
接着调用entry的writeTo()方法写进缓存。
这里写图片描述
#####Cache类的get()方法
它用来从缓存中读取响应体
这里写图片描述

####(4) ConnectInterceptor
这是连接拦截器。
这里写图片描述

####(5)CallServerInterceptor
负责将我们的http请求写进网络io中,并且从网络io中读取服务端返回的数据。
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值