OkHttp拦截器的实现原理

今天项目中遇到需要将从push接收到的数据按照协议parse成应用层需要的结构化数据类型问题;因为push消息类型繁多,等待解析出的结构化数据类型也多样,有的还需要经过几步的parse过程;而且因为项目历史原因,使用Protocal Buffer(push的数据是字节形式的传递)。中间尝试了代理、装饰等模式,都失败了,最终还是使用了原始的继承解决问题;在解决问题个过程中也学习了下OkHttp中的拦截器实现,这里做简单记录:

  • ﷒拦截器的接口定义如下:

  

可以看到,在拦截器的回调中,我们可以拿到两个重要的参数Request和Response,而接口在回调时,会接收一个Chain类型的参数,这个参数保存了Request和Response的相关数据。

  • 看一个简单的Interceptor接口实现例子:

    

该拦截器实例的功能只是在请求发出前和接收到响应后,分别打印log。Response response=chain.proceed(request); 很重要,它是将拦截连串起来的关键。

  • 再看下,一个网络请求的应用吧:

       

跟进,OkHttpClient.Builder的addInterceptor()方法,可以看到,在OkHttp内部是使用了List保存了添加的所有拦截器。

   

  • 跟进client.newCall(request).execute();的执行过程,查看拦截器的串联过程:

    

从上面的方法中可以看到,请求默认会被构造成RealCall类型,再进一步查看RealCall的execute()方法:

   

上面的红色方框中这行代码,它并没有真正的执行网络请求,而只是简单地将请求放入请求池中,让它等待分派器的后续执行。而真正的执行体在上面的蓝色方框中,它封装了一个拦截器链(Chain),并调用了Chain的proced方法,传入原始的request对象,这里开始拦截器链的调用过程:

   

  • 查看proceed方法,可以看到,它使用循环+递归的方式,借助函数调用栈,将拦截器串联起来:

     

上面的代码中,真正执行网络请求的是最后一行绿色方框中的代码,而当存在多个拦截器时,每个拦截器在执行时都会在上图的蓝色方框中的代码地方阻塞,等待下一个拦截器的调用返回。

  •  为了说明清楚,下面分别以 拦截器链中有1个、2个拦截器的场景加以模拟:

  

 

转载于:https://www.cnblogs.com/LuLei1990/p/5534791.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值