OkHttp 拾遗

(一)Interceptor chain

OkHttp 的 Interceptor chain 是比较特色的一个东西。我们通过添加自定义的 Interceptor 可以对请求的前、后做一些额外的拦截处理,然而实际上 OkHttp 框架的核心流程也是通过它实现的,以下是 RealCall 中的 getResponseWithInterceptorChain() 方法:

Response getResponseWithInterceptorChain() throws IOException {
  // Build a full stack of interceptors.
  List<Interceptor> interceptors = new ArrayList<>();

  // 用户自定义的 interceptor
  interceptors.addAll(client.interceptors());

  // 负责失败重试以及重定向的
  interceptors.add(retryAndFollowUpInterceptor);

  /** Bridges from application code to network code.
     * First it builds a network request from a user request. 
     * Then it proceeds to call the network. 
     * Finally it builds a user response from the network response. */
  interceptors.add(new BridgeInterceptor(client.cookieJar()));

  /** Serves requests from the cache and writes responses to the cache. */
  interceptors.add(new CacheInterceptor(client.internalCache()));

  /** Opens a connection to the target server and proceeds to the next interceptor. */
  interceptors.add(new ConnectInterceptor(client));

  if (!forWebSocket) {
    interceptors.addAll(client.networkInterceptors());
  }

  /** This is the last interceptor in the chain. It makes a network call to the server. */
  interceptors.add(new CallServerInterceptor(forWebSocket));

  Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0, originalRequest);
  return chain.proceed(originalRequest);
}

Interceptor chain 是个 责任链模式

它包含了一些命令对象和一系列的处理对象,每一个处理对象决定它能处理哪些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象。该模式还描述了往该处理链的末尾添加新的处理对象的方法。

Interceptor 便是这样,它首先实现自己的职责,比如 BridgeInterceptor 首先通过客户端的 request 创建一个 Request.Builder,然后调用下一个 Interceptor(也就是 CacheInterceptor,可以参考下图中 Interceptor 的调用顺序) 的 proceed 来得到 response,

Response networkResponse = chain.proceed(requestBuilder.build());

最后构建一个新的 Response.Builder 并返回。

OkHttp 流程图

其实 Interceptor 的设计也是一种分层的思想,每个 Interceptor 就是一层,分层简化了每一层的逻辑,每层只需要关注自己的责任(单一原则思想也在此体现),而各层之间通过约定的接口/协议进行合作(面向接口编程思想),共同完成复杂的任务。

(二)自定义 Interceptor
  1. 比如请求中添加统一的 header 和 QueryParameter;
  2. 没有网络的情况下,尝试使用 cache。
    ……
private static class RequestInterceptor implements Interceptor {
        @Override
        public Response intercept(@NonNull Chain chain) throws IOException {
                Request.Builder requestBuilder = chain.request().newBuilder();
                requestBuilder.addHeader("os_name", "Android");
                ……
                return chain.proceed(requestBuilder.build());
        }
  }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,841评论 18 139
  • 关于okhttp是一款优秀的网络请求框架,关于它的源码分析文章有很多,这里分享我在学习过程中读到的感觉比较好的文章...
    蕉下孤客阅读 3,616评论 2 38
  • 安卓开发领域,很多重要的问题都有了很好的开源解决方案,例如网络请求 OkHttp + Retrofit 简直就是不...
    我是涛锅锅阅读 507评论 0 0
  • 用OkHttp很久了,也看了很多人写的源码分析,在这里结合自己的感悟,记录一下对OkHttp源码理解的几点心得。 ...
    蓝灰_q阅读 4,337评论 4 34
  • 美容养颜抗衰老 是个永恒的话题 所有的女性都关心这个话题。 市面上有无数的美瞳化妆品, 但要找到一个既能美容又不损...
    蓝蝶_8263阅读 415评论 0 0