“深入交流“系列:Okhttp(一)请求流程解析

本文深入剖析Okhttp的请求流程,从同步和异步请求的区别开始,详细解释了构建OkhttpClient对象、Request对象、Call对象以及发送异步请求的过程。重点分析了Dispatcher分发器的角色和线程池管理,以及Interceptor拦截器在网络请求中的作用。最后总结了整个异步请求的流程,为理解Okhttp的内部工作机制提供了清晰的脉络。
摘要由CSDN通过智能技术生成

Okhttp请求流程源码解析

前言

最近发现以前学习过的好多东西,都忘记了,所以打算复习一次,并且通过输出博客来加深印象。Okhttp准备分成两篇文章来讲解,这篇文章主要叙述一下Okhttp的整体请求流程,第二篇文章则讲述一下Okhttp中极为重要的拦截器。“深入交流”系列打算从一些第三方框架源码或者FrameWork层源码入手,进行"深入"的交流,会持续输出下去,敬请期待。

1、Okhttp的同步请求和异步请求

在分析Okhttp的源码之前,我们首先了解一下Okhttp最基本的实现一次网络请求的方式。

Okhttp的同步请求,如下:

//[1]、创建OkhttpClient对象
OkHttpClient client = new OkHttpClient.Builder()
        .readTimeout(5000, TimeUnit.MILLISECONDS)
        .build();

//[2]、请求报文创建,包含常用的请求信息,如url、get/post方法,设置请求头等
Request request = new Request.Builder()
        .url("http://www.baidu.com")
        .get()
        .build();

//[3]、创建Call对象
Call call = client.newCall(request);

try {
    //[4]、同步请求,发送请求后,就会进入阻塞状态,直到收到响应
    Response response = call.execute();
    Log.d(TAG, "requestNet: response");
} catch (IOException e) {
    e.printStackTrace();
} 

接下来看一下okhttp的异步网络请求,如下:

// [1]、创建OkhttpClient对象
OkHttpClient client = new OkHttpClient.Builder()
        .readTimeout(5000, TimeUnit.MILLISECONDS)
        .build();

// [2]、请求报文创建,包含常用的请求信息,如url、get/post方法,设置请求头等
Request request = new Request.Builder()
        .url("http://www.baidu.com")
        .get()
        .build();

// [3]、创建Call对象
Call call = client.newCall(request);
// [4]、发送异步请求,接收回调信息
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        Log.d(TAG, "onFailure: request error......");
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        Log.d(TAG, "onResponse: request success......");
    }
}); 

可以看到同步请求和异步请求的使用在前3步都是相同的,只用在第4步的时候同步请求调用的是call.execute()方法,异步请求调用的是call.enqueue()方法。接下来我们会根据异步请求来分析一下Okhttp整体的请求流程,同步请求相对于异步请求来说,较为简单,掌握异步请求后再看同步请求,问题不大。。。

在正式分析源码之前我们先来看一下Okhttp的请求流程图,从宏观的角度先对整体的请求流程有个印象,之后我们再从每一步流程的细节进行分析。我自己把整体的请求分成了8个小步骤,在这8步中,Dispatcher较为重要,而Interceptors作为整个网络请求的核心部分,那是相当重要。

okhttp流程 .png

2、异步请求流程分析

[1]、构建OkhttpClient对象

OkhttpClient:相当于配置中心,所有的请求都会共享这些配置,OkhttpClient中定义了网络协议、DNS、请求时间等等。创建对象的方式有两种,一种是通过直接new对象的方式,另一种是通过Builder模式设置参数来进行创建。

方法一:使用默认参数,不需要配置参数
OkHttpClient client = new OkHttpClient();
方法二:通过Builder来配置参数
OkHttpClient client = new OkHttpClient.Builder()
        .readTimeout(5000, TimeUnit.MILLISECONDS)
        .build(); 

两者的构造方法分别如下:

// 默认方式,这种方式不需要配置参数,使用的都是默认创建的参数
public OkHttpClient() {
    this(new Builder());
}
// builder模式,通过Builder来配置参数
OkHttpClient(Builder builder) {
    this.dispatcher = builder.dispatcher;
    this.proxy = builder.proxy;
    this.protocols = builder.protocols;
    // 太多了,省略一部分
    ......
}

public Builder() {
    //调度器,用于调度后台发起的网络请求,有后台总请求数和单主机总请求数的控制。
    dispatcher = new Dispatcher();
    //⽀持的应⽤层协议,即 HTTP/1.1、HTTP/2 等
    protocols = DEFAULT_PROTOCOLS;
    //应⽤层⽀持的 Socket 设置,即使⽤明⽂ 传输(⽤于 HTTP)还是某个版本的 TLS(⽤于 HTTPS)。
    connectionSpecs = DEFAULT_CONNECTION_SPECS;
    eventListenerFactory = EventListener.factory(EventListener.NONE);
    proxySelector = ProxySelector.getDefault();
    //管理 Cookie 的控制器。OkHttp 提供了 Cookie 存取的判断⽀持(即什么时候需要存 Cookie,什么时候需要读取Cookie,但没有给出具体的存取实现。
    //如果需要存取 Cookie,你得⾃⼰写实现,例如⽤ Map 存在内存⾥,或者⽤别的⽅式存在本地存储或者数据库
    cookieJar = CookieJar.NO_COOKIES;
    socketFactory = SocketFactory.getDefault();
    //⽤于验证 HTTPS 握⼿过程中下载到的证书所 属者是否和⾃⼰要访问的主机名⼀致
    hostnameVerifier = OkHostnameVerifier.INSTANCE;
    certificatePinner = CertificatePinner.DEFAULT;
    proxyAuthenticator = Authenticator.NONE;
    authenticator = Authenticator.NONE;
    //客户端和服务器之间的连接抽象为一个connection,
    //每一个connection都会放到连接池当中,当请求的url是相同的时候可以进行复用
    connectionPool = new ConnectionPool();
    dns = Dns.SYSTEM;
    followSslRedirects = true;
    followRedirects = true;
    //在请求失败的时候是否⾃动重试。注意,⼤多数的请求失败并不属于 OkHttp 所定义的「需要重试」,
    //这种重试只适⽤于「同⼀个域名的 多个 IP 切换重试」「Socket 失效重试」等情况
    retryOnConnecti
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值