Android OkHttp拦截器源码分析一--简介

2018-10-07  本文已影响0人  青果果

拦截器OkHttp强大功能

拦截器使用了责任链设计模式,Okhttp源码中拦截器共有五个

在拦截器中我们可以做自定义缓存,设置网络请求重试次数,以及打印网络请求日志
等等...很多其他网络请求框架实现不了的需求

1. RetryAndFollowUpInterceptor

2. BridgeInterceptor

普通的拦截器,加统一的请求头等Content-Type Connection Content-Length Cookie
处理返回的结果,数据压缩用ZipSource,保存Cookie

3. CacheInterceptor

缓存拦截器,在缓存可用的情况下,读取本地缓存数据,如果没有缓存,请求服务器
先判断有没有缓存策略,拿到缓存过期时间,如果缓存过期了需要加一些头部信息
如果后台返回304,表示可以用缓存,每次拿到结果后做缓存处理
307 重定向 Location

4. ConnectInterceptor

连接拦截器
findHealthyConnection()会去缓存池里查找可用的连接,无可用就创建新的
OkHttp 是基于原生的 Socket + OkIO封装

5. CallServerInterceptor

写和读取数据

拦截器执行顺序

看源码就知道执行顺序是
retryAndFollowUpInterceptor-》BridgeInterceptor-》CacheInterceptor-》ConnectInterceptor-》CallServerInterceptor

Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());
    interceptors.add(retryAndFollowUpInterceptor);
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    interceptors.add(new CacheInterceptor(client.internalCache()));
    interceptors.add(new ConnectInterceptor(client));
    if (!forWebSocket) {
      interceptors.addAll(client.networkInterceptors());
    }
    interceptors.add(new CallServerInterceptor(forWebSocket));
    Interceptor.Chain chain = new RealInterceptorChain(
        interceptors, null, null, null, 0, originalRequest);
    return chain.proceed(originalRequest);
  }

但是看上面这段源码发现好像并不是只有这五种对吧!
有两句代码,分别是addAll方法,添加了两个集合,集合存储的是啥?

这里其实是自定义拦截器,可以看到,自定义拦截器添加的顺序分别又有两种
根据顺序分别叫做:Application Interceptors和Network Interceptors
集合嘛,也就是说我们可以添加多个自定义拦截器,自由发挥,实现各种需求

okhttp GitHub关于拦截器的介绍
链接:https://github.com/square/okhttp/wiki/Interceptors

//添加Application Interceptors
interceptors.addAll(client.interceptors());
...
//添加Network Interceptors
if (!forWebSocket) {
    interceptors.addAll(client.networkInterceptors());
}
官方拦截器示意图

注册Application Interceptors

OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(new XXXInterceptor())
    .build();

注册Network Interceptors

OkHttpClient client = new OkHttpClient.Builder()
    .addNetworkInterceptor(new XXXInterceptor())
    .build();

OkHttpClient的源码,可以看到定义了两个集合来存储我们注册的自定义拦截器

public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
  ...
  final List<ConnectionSpec> connectionSpecs;
  final List<Interceptor> interceptors;
  final List<Interceptor> networkInterceptors;

  public Builder addNetworkInterceptor(Interceptor interceptor) {
      if (interceptor == null) throw new IllegalArgumentException("interceptor == null");
      networkInterceptors.add(interceptor);
      return this;
  }

  public Builder addInterceptor(Interceptor interceptor) {
      if (interceptor == null) throw new IllegalArgumentException("interceptor == null");
      interceptors.add(interceptor);
      return this;
  }
}
上一篇下一篇

猜你喜欢

热点阅读