Android OkHttp 你真的懂它吗?(一)

Android OkHttp 你真的懂它吗?

看到这个标题,你可能会说:“我每天都用okhhtp,我怎么可能不懂呢?”。既然大家这么自信,那么下面我就要对大家进行灵魂拷问了,
1.为什么要用Okhttp,难道就是因为github start数,它到底好在哪里?
2. OkHttp请求整体流程是怎么样?
3.分发器是如何工作的?
4.拦截器是如何工作的 ?
5.应用拦截器和网络拦截器是什么,有什么区别?
6.okhttp如何复用TCP连接
最好的学习的方法,就是带着问题来学习,下面我们就给大家一一的讲解,以下代码是基于4.9.3最新的稳定版本

 implementation("com.squareup.okhttp3:okhttp:4.9.3")
为什么要用Okhttp,难道就是因为github start数,它到底好在哪里?

这个问题其实是考查大家对于OkHttp的特点以及特性,在github Okhttp的官网上面其实就有相关的介绍
大家可以看在首页就看到以下几句话 https://square.github.io/okhttp/

  1. 支持http2 并允许对同一个主机的请求共享同一个套接字(多路复用)

  2. http2以下的 通过连接池完成对套接字的复用

  3. 默认GZIP 压缩数据

  4. 响应缓存 ,避免了重复请求的网络 (这一项有限制必须是GET请求,Cache默认是关闭的)
    有必要带大家回顾下一次完整的Http的全过程,请看图

    完整的http请求流程
    在完成DNS域名解析之后,我们就得到了服务器的真实IP端口号,就要创建socket对象与服务器进行交互了,socket对象是非常稀缺的系统资源,多路复用帮我们优化了这个情况,java NIO就是采用的多路复用,客户端发送的连接请求都会注册到某个列表中,服务端只要对这个列表进行轮询,对于就绪的事件进行处理,整个过程通过单线程完成。未就绪的事件不会像阻塞模型那样阻塞线程,没有事件发生时也不会像非阻塞模型那样空转。HTTP2就支持多路复用,而Okhttp也帮我们封装好了。HTTP2以下okhttp是通过同一个host来复用套接字。GZIP就一种数据压缩格式,能够减少数据的大小,从而降低了服务器的压力。

OkHttp请求整体流程是怎么样?

我们先来简单的GET请求的代码

    fun test() {
        val okHttpClient = OkHttpClient().newBuilder().build() // 创建okhttpClient
        val request = Request.Builder().get().url("https://www.baidu.com/").build()  // 创建Request
        val newCall = okHttpClient.newCall(request)// 得到RealCall 
        val response = newCall.execute()            //  同步请求返回response
        println("请求是否成功:${response.isSuccessful}")  // 
        println(response.body?.string())
    }

通过以上的代码可以初略的画一张图
大致流程
按照上面的大致的流程图我们一步步详细的说明下这个问题
1.构建我们请求的客户端OkhttpClient对象,内部使用到了构造器设计模式,可以对我们请求进行设置,选项也非常多,下面说几个常用的选项

        val okHttpClient = OkHttpClient()
            .newBuilder()
                // 读写连接超时时间
            .readTimeout(10,TimeUnit.SECONDS)
            .writeTimeout(10,TimeUnit.SECONDS)
            .connectTimeout(10,TimeUnit.SECONDS)
                // 添加自定义应用拦截拦截器
            .addInterceptor {
                
            }
            // 一般我们都会添加日志拦截器
            .addInterceptor (HttpLogginIntercept())
               // 添加自定义网络拦截器
            .addNetworkInterceptor {

            }
              // 设置Cookie
            .cookieJar()
              // 线上项目大家基本都是https 设置用于保护HTTPS连接的套接字工厂和信任管理器
            .sslSocketFactory()
                // 设置缓存策略
            .cache()
            .build()

2.通过Request对象得到我们RealCall 然后添加到我们Dispatcher分发器中进行请求管理,如果是同步请求执行excute方法,就直接添加我们 runningSyncCalls 同步等待队列中去,finished之后就会从队列中进行移除,如果是异步请求执行enqueue方法,先要添加readyAsyncCalls等待队列当中去,下面就要进行判断了
(1)当前异步请求的数量 runningAsyncCalls 是否大于64
(2)同一host请求数是否大于5个
满足这两个条件就将等待队列的任务添加执行runningAsyncCalls 正在执行任务队列,并且将这些realCall添加到线程池中进行执行 ,下面大家想都不用想,肯定会执行RealCall 的run方法对不对,同理在finally里面会调用登发器的finished方法,再进行一次
ready队列的轮训,给大家画个图这样方便大家理解
分发器的分发流程

下面就要进入okhttp 的核心部分拦截器,为了看的更舒服还是分开写

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值