分析的很全面,推荐给大家
OKHTTP拦截器缓存策略CacheInterceptor的简单分析
OKHTTP拦截器ConnectInterceptor的简单分析
OKHTTP拦截器CallServerInterceptor的简单分析
OKHTTP拦截器BridgeInterceptor的简单分析
OKHTTP拦截器RetryAndFollowUpInterceptor的简单分析
1、LoggingInterceptor示例代码
通过下面的代码可以看出,它就是用于在请求发送前和网络响应后的打印日志信息的拦截器。具体打印的内容很简单,就不解释了,重点是 Application Intercetor 和 NetworkInterceptor 的区别,继续往下看。
class LoggingInterceptor implements Interceptor{
@Override
public Responseintercept(Interceptor.Chain chain)
throws IOException{
Request request = chain.request();
//请求前--打印请求信息
longt1 = System.nanoTime();
logger.info(String.format("Sending request %s on %s%n%s", request.url(), chain.connection(), request.headers()));
//网络请求Response response = chain.proceed(request);
//网络响应后--打印响应信息longt2 = System.nanoTime();
logger.info(String.format("Received response for %s in %.1fms%n%s", response.request().url(), (t2 - t1) /1e6d, response.headers()));returnresponse; }}
2、Application Intercetor和NetworkInterceptor的区别
在官方文档中用 LoggingInterceptor 作为示例,解释了 Application Intercetor 和 NetworkInterceptor 的区别。
OKHTTP官网示例在看两种拦截器的区别之前,还是要点击这个链接去看看,之后再看这个博客的总结会好点。
到这里,默认就是已经看过了官网的示例了,那我们就使用一个图来看看拦截器的调用过程:
拦截器的执行过程.png
从上面的调用关系可以看出除了红色圈出的拦截器之外都是系统提供的拦截器,这整个过程是递归的执行过程,在 CallServerInterceptor 中得到最终的 Response 之后,将 response 按递归逐级进行返回,期间会经过 NetworkInterceptor 最后到达自定义的 Interceptor 。
在官网给出的 NetworkInterceptor 和 Application Interceptor 的区别在上面的图中就可以看出:
1.自定义 Interceptor 是第一个 Interceptor 因此它会被第一个执行,因此这里的 request 还是最原始的,并没有经过 BridgeInterceptor 进行加工过,因此他只有一个自定义的 User-Agent 请求头。而对于 response 而言呢,因为整个过程是递归的调用过程,因此它会在 CallServerInterceptor 执行完毕之后才会将 Response 进行返回,因此这里得到的 response 就是最终的响应,虽然中间有重定向,但是这里只关心最终的 response 。
2.NetwrokInterceptor 处于第 6 个拦截器中,它会经过 RetryAndFollowIntercptor 进行重定向并且也会通过 BridgeInterceptor 进行 request 请求头和 响应 resposne 的处理,因此这里可以得到的是更多的信息。在打印结果可以看到它内部是发生了一次重定向操作,在上图可以看出,为什么 NetworkInterceptor 可以比 Application Interceptor 得到更多的信息了。
3、两种拦截器的区别
下面是官网给出的区别,根据我自己的理解,使用中文标出了自己的解释。
Application interceptors
Don't need to worry about intermediate responses like redirects and retries.不需要去关心中发生的重定向和重试操作。
Are always invoked once, even if the HTTP response is served from the cache.只会被调用一次,即使这个响应是从缓存中获取的。
Observe the application's original intent. Unconcerned with -OkHttp-injected headers like If-None-Match.只关注最原始的请求,不去关系请求的资源是否发生了改变,我只关注最后的 response 结果而已。
Permitted to short-circuit and not call Chain.proceed().因为是第一个被执行的拦截器,因此它有权决定了是否要调用其他拦截,也就是 Chain.proceed() 方法是否要被执行。
Permitted to retry and make multiple calls to Chain.proceed()
.因为是第一个被执行的拦截器,因此它有可以多次调用 Chain.proceed() 方法,其实也就是相当与重新请求的作用了。
Network Interceptors
Able to operate on intermediate responses like redirects and retries.因为 NetworkInterceptor 是排在第 6 个拦截器中,因此会经过 RetryAndFollowup 进行失败重试或者重定向,因此可以操作中间的 resposne。
Not invoked for cached responses that short-circuit the network.这个我不知道是什么意思,望大神指点。TODO
Observe the data just as it will be transmitted over the network.观察数据在网络中的传输,具体我也不太清除是干嘛的。TODO
Access to the Connection that carries the request.因为它排在 ConnectInterceptor 后执行,因此返回执行这个 request 请求的 Connection 连接。
在上面还有几个 TODO 没有解决,希望懂的同学指点一下...