美文网首页
Android知名三方库OKHttp(三) - 拦截器源码分析

Android知名三方库OKHttp(三) - 拦截器源码分析

作者: 信仰年輕 | 来源:发表于2021-06-24 18:58 被阅读0次

    源代码
    GitHub源代码

    本文目标

    理解okhttp的拦截器各自的作用

    拦截器

    在发起请求的时候,当执行到execute()方法会调用

     Response result = getResponseWithInterceptorChain();
    

    这行代码,就是通过责任链模式的拦截器拿到响应的,具体代码如下

    final class RealCall implements Call {
    
      @Override public Response execute() throws IOException {
        synchronized (this) {
          if (executed) throw new IllegalStateException("Already Executed");
          executed = true;
        }
        captureCallStackTrace();
        eventListener.callStart(this);
        try {
          client.dispatcher().executed(this);
          Response result = getResponseWithInterceptorChain();
          if (result == null) throw new IOException("Canceled");
          return result;
        } catch (IOException e) {
          eventListener.callFailed(this, e);
          throw e;
        } finally {
          client.dispatcher().finished(this);
        }
      }
    
      Response getResponseWithInterceptorChain() throws IOException {
        // Build a full stack of interceptors.
        // 拦截器的一个集合
        List<Interceptor> interceptors = new ArrayList<>();
        // 客户端的所有自定义拦截器
        interceptors.addAll(client.interceptors());// 自己的
        // OKhttp 5 个拦截器 ,责任链设计模式,每一个拦截器只处理与他相关的部分 
        interceptors.add(retryAndFollowUpInterceptor);// 重试
        interceptors.add(new BridgeInterceptor(client.cookieJar()));// 基础
        interceptors.add(new CacheInterceptor(client.internalCache()));// 缓存
        interceptors.add(new ConnectInterceptor(client));// 建立连接
        interceptors.add(new CallServerInterceptor(forWebSocket));// 写数据
    
        Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
            originalRequest, this, eventListener, client.connectTimeoutMillis(),
            client.readTimeoutMillis(), client.writeTimeoutMillis());
    
        return chain.proceed(originalRequest);
      }
    }
    

    我们自己也可以实现 Interceptor 接口来自定义拦截器,okhttp会先将我们的拦截器添加到集合中,下面的5个拦截器都是okhttp自带的拦截器

    1.RetryAndFollowUpInterceptor

    处理重试的一个拦截器,会去处理一些异常,只要不是致命的异常就会重新发起一次请求(把Request给下级),如果是致命的异常就会抛给上一级;
    会处理一些重定向等等,比如3XX 307,407就会从头部中获取新的路径,生成一个新的请求交给下一级(重新发送一次请求)

    2.BridgeInterceptor

    做一个简单的处理,设置一些通用的请求头,Content-Type,Connection,Content-Length,Cookie
    做一些返回的处理,如果返回的数据被压缩了采用 ZipSource,保存Cookie

    3.CacheInterceptor

    在缓存可用的情况下,读取本地的缓存的数据,如果没有直接去服务器,如果有首先判断有没有缓存策略,然后判断有没有过期,如果没有过期直接拿缓存,如果过期了需要添加一些之前头部信息如:If-Modified-Since,这个时候后台有可能会给你返回 304 代表你是可以拿本地缓存,每次读取到新的响应后做一次缓存

    4.ConnectInterceptor

    findHealthyConnection()找一个连接,首先判断有没有健康的,没有就创建(建立Socket,握手连接),连接缓存
    okHttp是基于原生的 Socket + okio (原生IO的封装)
    封装 HttpCodec 里面封装了okio的 Source(输入) 和 Sink(输出),我们通过 HttpCodec 就可以操作 Socket的输入输出,我们就可以向服务器写数据和读取返回数据

    5.CallServerInterceptor

    写数据和读取数据
    写头部信息,写body表达信息等等

    连接的三个核心类

    • RealConnection 建立连接的一个对象的封装
    • ConnectionPool 保存了连接
    • StreamAllocation 找一些链接,做一下封装

    相关文章

      网友评论

          本文标题:Android知名三方库OKHttp(三) - 拦截器源码分析

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