OKHttp源码解析(二)——拦截器

学习参考资料:OKHttp源码解析  OKHttp源码分析——拦截器  OKhttp完全解析-拦截器

上一篇大概记录了一下OKHttp的整体结构设计,这里引用泡网的一张总体设计图

OKHttp总体设计

上面这张就是OKHttp总体设计图了,它主要是通过Dispatcher不断从RequestQueue中取出请求(Call),根据是否已缓存调用Cache或 Network这两类数据获取接口之一,从内存缓存或是服务器取得请求的数据。该引擎有同步和异步请求,同步请求通过Call.execute()直接返 回当前的Response,而异步请求会把当前的请求Call.enqueue添加(AsyncCall)到请求队列中,并通过回调(Callback) 的方式来获取最后结果。

enqueue队列

这里可以看到mOkHttpClient.newCall(rq).enqueue(newMyCallBack(parser) {});中的Call.enqueue其实就是最终会执行将一个Call转换为一个AsyncCall添加到队列中,这里的分发队列,会在后续笔记中详细介绍。

上一篇笔记中提到,AsyncCall继承了NamedRunnable实现了它的抽象方法execute()

execute

execute方法里面是调用了getResponseWithIntercepteorChain()方法获取服务器的返回,然后调用getDispatcher().finish();通知任务分发器该任务已结束。

getResponseWithIntercepteorChain():顾名思义,通过这个拦截器链中的每一个拦截器之后得到服务器的返回结果。

看源码中这个方法得知我们的猜想没有错,他就是一个构建了一个拦截器链,通过依次执行该拦截器链中的每一个拦截器最终得到服务器返回。

官方文档的解释:观察,修改以及可能短路的请求输出和响应请求的回来。通常情况下拦截器用来添加,移除或者转换请求或者回应的头部信息。

Intercepteor

这个方法的实现其实就是将很多个拦截器包括框架内部的,用户自定义的,统统放到一个拦截器数组里,创造这个RealInterceptorChain这个拦截器链,最后实现这个proceed()这个方法

proceed

通过源码我们可以看到,这个proceed()方法中采用列表的形式追踪拦截器,拦截器会被有序调用

创建下一个拦截链。传入index + 1使得下一个拦截器链只能从下一个拦截器开始访问

执行索引为index的intercept方法,并将下一个拦截器链传入该方法

    通过官方文档的描述以及源码的分析,我们心中对拦截器大概有个理解印象了,下面,就记录一下,不同的拦截器实现的不同方法:

1.RetryAndFollowUpInterceptor:负责失败重试以及重定向

RetryAndFollowUpInterceptor

以此为例,可以看到一行很关键的代码,response= ((RealInterceptorChain) chain).proceed(request, streamAllocation,null,null);

这行代码就是执行下一个拦截器链的proceed方法。而我们知道在下一个拦截器链中又会执行下一个拦截器的intercept方法。所以整个执行链就在拦截器与拦截器链中交替执行,最终完成所有拦截器的操作。这也是OkHttp拦截器的链式执行逻辑。

一个拦截器的intercept方法所执行的逻辑大致分为三部分:

在发起请求前对request进行处理

调用下一个拦截器,获取response

对response进行处理,返回给上一个拦截器

这就是OkHttp拦截器机制的核心逻辑。所以一个网络请求实际上就是一个个拦截器执行其intercept方法的过程。而这其中除了用户自定义的拦截器外还有几个核心拦截器完成了网络访问的核心逻辑,按照先后顺序依次是:

RetryAndFollowUpInterceptor

BridgeInterceptor

CacheInterceptor

ConnectIntercetot

CallServerInterceptor

RetryAndFollowUpInterceptor:如上文代码所示,RetryAndFollowUpInterceptor负责两部分逻辑:在网络请求失败后进行重试,当服务器返回当前请求需要进行重定向时直接发起新的请求,并在条件允许情况下复用当前连接

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

BridgeInterceptor主要负责以下几部分内容:1.设置内容长度,内容编码 2.设置gzip压缩,并在接收到内容后进行解压。省去了应用层处理数据解压的麻烦,3.添加cookie 4.设置其他报头,如User-Agent,Host,Keep-alive等。其中Keep-Alive是实现多路复用的必要步骤

3.CacheInterceptor :负责读取缓存直接返回、更新缓存

CacheInterceptor的职责很明确,就是负责Cache的管理:1.当网络请求有符合要求的Cache时直接返回Cache;2.当服务器返回内容有改变时更新当前cache;3.如果当前cache失效,删除

4.ConnectIntercetot:负责和服务器建立连接

ConnectInterceptor

ConnectInterceptor的intercept方法只有一行关键代码:

RealConnection connection= streamAllocation.connection();

即为当前请求找到合适的连接,可能复用已有连接也可能是重新创建的连接,返回的连接由连接池负责决定。

5.CallServerInterceptor:负责向服务器发送请求数据、从服务器读取响应数据

CallServerInterceptor负责向服务器发起真正的访问请求,并在接收到服务器返回后读取响应返回。

图片及解释来源:https://yq.aliyun.com/articles/78104?t=t1

最后补充一句,拦截器分为网络拦截器和应用拦截器,注册网络拦截器和注册应用拦截器很类似。只是通过networkInterceptors()方法取代了interceptore()方法。

注册网络拦截器:client.networkInterceptors().add(new xxxInterceptor);

注册应用拦截器:client.interceptore().add(new xxxInterceptor);

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容