目录
应用拦截器(Application Interceptors)
-
拦截器的分类
拦截器是一个强大的机制,可以监视,重写,重连接等,主要是通过职责链的方式对请求进行拦截处理。SDK中包含几个默认既定的拦截器,主要有重连接、缓存等多个拦截器,以及用户自定义的应用拦截器(Application Interceptors)和网络拦截器(Network Interceptors)。
-
拦截器各自的优点概述
-
应用拦截器(Application Interceptors)
- 无需担心中间响应,例如重定向和重试。
- 即使从缓存提供HTTP响应,也总是被调用一次。
- 遵守应用程序的原始意图。不关心OkHttp注入的标头,例如
If-None-Match
。- 允许短路而调用
Chain.proceed()
。- 允许通过多次调用
Chain.proceed()
重连接。- 可以使用withConnectTimeout,withReadTimeout,withWriteTimeout调整连接超时
-
网络拦截器(Network Interceptors)
- 能够对重定向和重试之类的中间响应进行操作。
- 响应缓存的而短路的调用不会调用网络拦截器。
- 观察数据,就像通过网络传输数据一样。
- 访问
Connection
带有请求的。
-
拦截器的执行流程分析
关于拦截器的执行流程分析,请参考另外一篇文章关于OkHttp的拦截器执行流程源码分析,了解到拦截器的执行可以更好的理解拦截器之间的区别。在这里我们也从RealCall的getResponseWithInterceptorChain来看一下拦截器的装载顺序。
List<Interceptor> interceptors = new ArrayList<>();
// 1.应用拦截器
interceptors.addAll(client.interceptors());
// 2.默认拦截器
interceptors.add(new RetryAndFollowUpInterceptor(client));// 重连拦截器
interceptors.add(new BridgeInterceptor(client.cookieJar()));// 桥拦截器
interceptors.add(new CacheInterceptor(client.internalCache()));// 缓存拦截器
interceptors.add(new ConnectInterceptor(client));// 连接拦截器
// 3.网络拦截器
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
从代码中我们看到拦截器队列是一个有序列表,并且装载顺序为应用拦截器、默认拦截器、网络拦截器。
-
应用拦截器分析
上文中已经提到了应用拦截器的优点,那么我们从源码角度来分析一下为什么应用拦截器具有这些优点和特点。
-
无需担心中间响应,例如重定向和重试。
重定向和重试这些逻辑是在默认拦截器中处理的,是在应用拦截器执行之后处理的;
-
即使从缓存提供HTTP响应,也总是被调用一次。
缓存逻辑是在默认拦截器CacheInterceptor中处理的,是在应用拦截器执行之后处理的,所以即使没有发起真正的网络请求,那么应用拦截器也会被执行;
-
遵守应用程序的原始意图。不关心OkHttp注入的标头,例如
If-None-Match
。
注入http head这些逻辑是在默认拦截器BridgeInterceptor中处理的,同样也是在应用拦截器之后处理,所以无需关注;
-
允许短路而不调用
Chain.proceed()
。
在应用拦截器中不调用Chain.proceed()
之后,后续都不会被调用;
-
允许通过多次调用
Chain.proceed()
重连接。
在应用拦截器中调用Chain.proceed()
之后,后续的默认拦截器和网络拦截器都会重新执行;
-
可以使用withConnectTimeout,withReadTimeout,withWriteTimeout调整连接超时。
同样由于应用拦截器在默认拦截器和网络拦截器之前,在实际发起网络之前执行,所以这时候可以调整连接超时;
-
网络拦截器分析
-
能够对重定向和重试之类的中间响应进行操作。
网络拦截器在默认拦截器RetryAndFollowUpInterceptor之后执行;
-
响应缓存的而短路的调用不会调用网络拦截器。
网络拦截器在默认拦截器RetryAndFollowUpInterceptor之后执行;
-
观察通过网络传输的数据。
-
访问承载请求的连接。