OkHttp源码核心类之一:拦截器简述

正文

OkHttp是什么

OkHttp是时下非常流行的网络编程框架,由行业巨佬Square公司开源,很多其他的流行框架比如retrofit的底层也是okhttp,只不过使用了注解反射动态代理将其进行了封装。
流行版本为:3.10.0,最新版本为:4.0.1,只不过将实现语言从java改成了kotlin。

相对于其他网络框架,有如下优点:

  • 支持SpdyHttp1.XHttp2Quic以及WebSocket
  • 连接池复用底层TCP(Socket),减少请求延时
  • 无缝的支持GZIP减少数据流量
  • 缓存响应数据减少重复的网络请求
  • 请求失败自动重试主机的其他ip,自动重定向

OkHttp怎么用

添加gradle依赖

dependencies {
   ....
    implementation("com.squareup.okhttp3:okhttp:4.0.1")
}

Java调用(同步请求,异步请求)

public class MyRequest {
    /**
     * 异步请求
     */
    public void sendReqAsync() {
        OkHttpClient client = new OkHttpClient.Builder().build();
        Request request = new Request.Builder().url("http://www.baidu.com").build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                Log.d("sendReqTag", "onFailure:" + e.getLocalizedMessage());
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                String s = new String().concat(response.code() + "/n")
                        .concat(response.message() + "/n")
                        .concat(response.body().string());
                Log.d("sendReqTag", "onSuccess/n " + s);
            }
        });
    }

    /**
     * 同步请求
     */
    public void sendReqSync() {
        OkHttpClient client = new OkHttpClient.Builder().build();
        Request request = new Request.Builder().url("http://www.baidu.com").build();
        Call call = client.newCall(request);
        try {
            Response response = call.execute();
            String s = new String().concat(response.code() + "/n")
                    .concat(response.message() + "/n")
                    .concat(response.body().string());
            Log.d("sendReqTag", "onSuccess/n " + s);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

OkHttp的简单使用方法大致使用如上,其中也有一些细节需要注意:

1、在应用层使用OkHttp,必然会涉及到4个重要元素:

  • OkHttpClient类(产生OkHttp客户端实例)
  • Request类(请求封装)
  • Call类(网络任务封装,并决定是要同步执行还是异步执行,注意,同步请求可以放在主线程中,但是异步请求可以 )
  • Response类(网络任务执行之后的回调)

2、执行网络请求必须在manifest中申请INTERNET权限,不然会抛异常.

3、完整的一个请求执行出去,流程如下图:
image.png


OkHttp源码核心类之一:分发器详解

上述,提到Call类,可以选择性执行 同步或者异步请求,但是无论同步异步,都一定会经过一个门户:"分发器" :
索引进源码(okhttp v3.10.0):

异步请求.png
同步请求.png

虽然用户不需要直接操作分发器,但是 分发器,作为OkHttp架构的一个门户层,是所有请求的必经之路,其中的代码还是有必要了解细节的。

同步请求

进入分发器 Dispatcher之后, 会执行 getResponseWithInterceptorChain() 来执行这个Call任务,得到一个Response,其中的细节分为两步:

1、client.dispatcher().executed(this); ,进入源码可以看到 仅仅是执行了 runningSyncCalls.add(call);,将call对象加入到了一个双端队列 Deque<RealCall> runningSyncCalls 中。
2、 getResponseWithInterceptorChain() 是执行网络请求的核心内容,涉及到拦截器,在这一节上暂时不详述。

同步请求的执行步骤十分简单,将任务加入到 runningSyncCalls列表,并且直接执行核心方法,同步阻塞拿到response。

《960全网最全Android开发笔记》

手把手讲解-OkHttp硬核知识点(1,事件分发流程

《379页Android开发面试宝典》

手把手讲解-OkHttp硬核知识点(1,事件分发流程

《507页Android开发相关源码解析》

手把手讲解-OkHttp硬核知识点(1,事件分发流程

因为文件太多,全部展示会影响篇幅,暂时就先列举这些部分截图

CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》