Android开发老生新谈:从OkHttp原理看网络请求,2024年最新阿里巴巴p6面试

本文深入探讨Android开发中的OkHttp网络请求,分析OkHttpClient、Request及RealCall的核心作用,揭示网络请求流程,包括用户自定义拦截器、重试与重定向、桥接拦截器、缓存拦截器、连接拦截器等。文中还介绍了调度器Dispatcher如何管理异步请求,以及连接建立过程。最后,文章提供了一份Android开发者的学习和进阶资源。
摘要由CSDN通过智能技术生成

这里有三个主要的类需要说明一下:OkHttpClient、Request以及RealCall

  • OkHttpClient: 相当于配置中⼼,可用于发送 HTTP 请求并读取其响应。它的配置有很多,例如connectTimeout:建⽴连接(TCP 或 TLS)的超时时间,readTimeout :发起请求到读到响应数据的超时时间,Dispatcher:调度器,⽤于调度后台发起的⽹络请求,等等。还有其他配置可查看源码。

  • Request: 一个主要设置网络请求Url请求方法(GET、POST…)请求头请求body的请求类。

  • RealCall: RealCall是由newCall(Request)方法返回,是OkHttp执行请求最核心的一个类之一,用作连接OkHttp的应用程序层和网络层,也就是将OkHttpClient和Request结合起来,发起异步和同步请求。

从上面的使用步骤可以看到,OkHttp最后执行的是okHttpClient.newCall(request).enqueue,也就是RealCall的enqueue方法,这是一个异步请求,同样的,也可以执行同步请求RealCall.execute()

RealCall的同步请求最后其实会调用RealCall.getResponseWithInterceptorChain(),而RealCall的异步请求是使用线程池先将请求放置到后台处理,但是最后还是会调用RealCall.getResponseWithInterceptorChain()来获取网络请求的返回值Response。从这里就基本能嗅到网络请求的核心其实与getResponseWithInterceptorChain()方法有关,那到底如何与服务器连接进行网络请求的?这个问题就先抛在这,后面再详细说。

我们先从异步请求enqueue开始,来看异步请求的主要结构。

类:Dispatcher

private fun promoteAndExecute(): Boolean {

val executableCalls = mutableListOf()

synchronized(this) {

val i = readyAsyncCalls.iterator()

while (i.hasNext()) {

val asyncCall = i.next()

if (runningAsyncCalls.size >= this.maxRequests) break // Max capacity.

if (asyncCall.callsPerHost.get() >= this.maxRequestsPerHost) continue // Host max capacity.

i.remove()

asyncCall.callsPerHost.incrementAndGet()

executableCalls.add(asyncCall)

runningAsyncCalls.add(asyncCall)

}

isRunning = runningCallsCount() > 0

}

for (i in 0 until executableCalls.size) {

val asyncCall = executableCalls[i]

asyncCall.executeOn(executorService)

}

return isRunning

}

异步请求首先会将AsyncCall添加到双向队列readyAsyncCalls中(即准备执行但还没有执行的队列),做请求的准备动作。接着遍历准备执行队列readyAsyncCalls,寻找符合条件的请求,并将其加入到一个保存有效请求的列表executableCalls和正在执行队列runningAsyncCalls中,而这个筛选条件主要有两条:

  • if (runningAsyncCalls.size >= this.maxRequests) break :并发执行的请求数要小于最大的请求数64。

  • if (asyncCall.callsPerHost.get() >= this.maxRequestsPerHost) continue :某个主机的并发请求数不能超过最大请求数5

也就是说,当我们的并发请求量超过64个或者某个主机的的请求数超过5,则超过的请求暂时不能执行,需要等一等才能再加入执行队列中。

将有效的请求筛选出后并保存,立即开始遍历请求,一一利用调度器Dispatcher里的ExecutorService进行Runnable任务,也就是遍历后加入到线程池中执行这些有效的网络请求。

类:RealCall.AsyncCall

override fun run() {

threadName(“OkHttp ${redactedUrl()}”) {

try {

val re

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值