OkHttp网络请求流程
经过前面多篇博客的铺垫,终于来了。让我们继续深入OkHttp源码,了解OkHttp网络请求的实现。
val requestBuilder: Request.Builder = Request.Builder()
...
val request: Request = requestBuilder.build()
val call: Call = okHttpClient.newCall(request)
在OkHttp的基本用法一文中我们了解到,拿到Call实例后,有两种网络请求:异步和同步。
1、异步请求
从Call的enqueue(responseCallback: Callback)方法开始:

从OkHttpClient调用newCall(Request)方法获取Call实例,返回的是RealCall对象:
/** Prepares the [request] to be executed at some point in the future. */
override fun newCall(request: Request): Call = RealCall(this, request, forWebSocket = false)
RealCall实现了Call接口,enqueue(responseCallback: Callback)方法实现如下:
override fun enqueue(responseCallback: Callback) {
check(executed.compareAndSet(false, true)) { "Already Executed" }
callStart()
client.dispatcher.enqueue(AsyncCall(responseCallback))
} 通过构造RealCall中的inner类AsyncCall封装当前的RealCall和Callback回调。并将其放入Dispatcher调度器中的异步等待队列readyAsyncCalls。
internal fun enqueue(call: AsyncCall) {
synchronized(this) {
readyAsyncCalls.add(call)
// Mutate the AsyncCall so that it shares the AtomicInteger of an existing running call to
// the same host.
if (!call.call.forWebSocket) {
val existingCall = findExistingCallWithHost(call.host)
if (existingCall != null) call.reuseCallsPerHostFrom(existingCall)
}
}
promoteAndExecute()
} 调用promoteAndExecute()方法推进任务队列的执行。
private fun promoteAndExecute(): Boolean {
this.assertThreadDoesntHoldLock()
val executableCalls = mutableListOf<AsyncCall>()
val isRunning: Boolean
synchronized(this) {
val i = readyAsyncCalls.iterator()
while (i.hasNext()) {
val asyncCall = i.next()
...
//将接下来执行的AsyncCall放入执行队列runningAsyncCalls中
runningAsyncCalls.add(asyncCall)
}
isRunning = runningCallsCount() > 0
}
for (i in 0 until executableCalls.size) {
val asyncCall = executableCalls[i]
asyncCall.executeOn(executorService)
}
return isRunning
} 再回到AsyncCall中,调用它的executeOn(executorService: ExecutorService)方法,传入Dispatcher中的执行器ExecutorService。
fun executeOn(executorService: ExecutorService) {
client.dispatcher.assertThreadDoesntHoldLock()
var success = false
try {
//通过现场执行当前任务
executorService.execute(this)
success = true
} catch (e: RejectedExecutionException) {
val ioException = InterruptedIOException("executor rejected")
ioException.initCause(e)
noMoreExchanges(ioException)
responseCallback.onFailure(this@RealCall, ioException)
} finally {
if (!success) {
client.dispatcher.finished(this) // This call is no longer running!
}
}
} 看到通过Executor执行自身,毫无疑问,AsyncCall继承自Runnable,直接看它的run()方法实现:
override fun run() {
...
try {
val response = getResponseWithInterceptorChain()
signalledCallback = true
responseCallback.onResponse(this@RealCall, response)
} catch (e: IOException) {
...
} catch (t: Throwable) {
...
} finally {
//最后,将执行过的AsyncCall从开始加入的runningAsyncCalls中移除
client.dispatcher.finished(this)
}
} 在run()中调用OkHttp网络请求核心方法:getResponseWithInterceptorChain(),经过层层拦截器调用链获取网络请求。这里暂不对该方法展开分析,在OkHttp拦截器Interceptor一文中详细分析。
拿到Response网络请求响应,回调直接创建网络请求时构造的Callback实例
interface Callback {
fun onFailure(call: Call, e: IOException)
fun onResponse(call: Call, response: Response)
} 最后,将执行过的异步任务从异步执行队列runningAsyncCalls中移除。
/** Used by [AsyncCall.run] to signal completion. */
internal fun finished(call: AsyncCall) {
call.callsPerHost.decrementAndGet()
finished(runningAsyncCalls, call)
}
2、同步请求
同步请求逻辑比异步请求要简单直接一些。

直接执行Call实例的execute()方法,该方法在RealCall类中实现:
override fun execute(): Response {
check(executed.compareAndSet(false, true)) { "Already Executed" }
timeout.enter()
callStart()
try {
client.dispatcher.executed(this)
return getResponseWithInterceptorChain()
} finally {
client.dispatcher.finished(this)
}
} 接着调用Dispatcher的execute()方法,是不是用Dispatcher执行呢?不是,只是将RealCall放到runningSyncCalls同步执行队列中,请求完毕最后在finally中移除。
/** Used by [Call.execute] to signal it is in-flight. */
@Synchronized internal fun executed(call: RealCall) {
runningSyncCalls.add(call)
} 紧接着才是getResponseWithInterceptorChain()OkHttp网络请求核心方法。该方法封装网络请求、拦截器、连接池等等,返回Response响应。所以直接执行execute()要放到子线程中。