美文网首页
Android OkHttp拦截器源码分析一--简介

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

作者: 青果果 | 来源:发表于2018-10-07 11:47 被阅读0次

    拦截器OkHttp强大功能

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

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

    1. RetryAndFollowUpInterceptor

    • 处理重试的拦截器,也会去处理一些异常
    • 只要不是致命的异常就会重新发起一次请求,如果是致命的异常就会抛给上一级
    • 处理重定向等问题3XX,307 会从头部获取新的路径,生成一个新的请求

    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;
      }
    }
    

    相关文章

      网友评论

          本文标题:Android OkHttp拦截器源码分析一--简介

          本文链接:https://www.haomeiwen.com/subject/hxeajftx.html