请求方式
代码语言:txt复制fun load() {
代码语言:txt复制 //1.创建请求(包含url,method,headers,body)
代码语言:txt复制 val request = Request
代码语言:txt复制 .Builder()
代码语言:txt复制 .url("")
代码语言:txt复制 .build()
代码语言:txt复制 //2.创建OkHttpClient (包含分发器、拦截器、DNS等)
代码语言:txt复制 val okHttpClient = OkHttpClient.Builder().build()
代码语言:txt复制 //3.创建Call(用于调用请求)
代码语言:txt复制 val newCall = okHttpClient.newCall(request)
代码语言:txt复制 //4.通过异步请求数据
代码语言:txt复制 newCall.enqueue(object :Callback{
代码语言:txt复制 override fun onFailure(call: Call, e: IOException) {}
代码语言:txt复制 override fun onResponse(call: Call, response: Response) {}
代码语言:txt复制 })
代码语言:txt复制 //4.通过同步请求数据
代码语言:txt复制 val response = newCall.execute()
代码语言:txt复制}
我们会按照顺序来分析一下请求的流程
前面1,2,3步很多文章已经分析过很多遍了 也比较简单 同学们可以自己看一下 我们就不再赘述 我们直接看第四步进入今天的主要流程
Okhttp请求分为同步方式和异步方式 不过最终都是殊途同归 我们以异步的方式分析一下请求流程
enqueue()
话不多说 先看一眼代码
代码语言:txt复制RealCall.enqueue()->
代码语言:txt复制Dispatcher.enqueue()->
代码语言:txt复制Dispatcher.promoteAndExecute()->
代码语言:txt复制RealCall.executeOn()
代码语言:txt复制override fun enqueue(responseCallback: Callback) {
代码语言:txt复制 synchronized(this) {
代码语言:txt复制 //检查是否已经开始运行
代码语言:txt复制 check(!executed) { "Already Executed" }
代码语言:txt复制 executed = true
代码语言:txt复制 }
代码语言:txt复制 callStart()
代码语言:txt复制 //封装AsyncCall对象 并放入队列中等待执行
代码语言:txt复制 client.dispatcher.enqueue(AsyncCall(responseCallback))
代码语言:txt复制 }
代码语言:txt复制internal fun enqueue(call: AsyncCall) {
代码语言:txt复制 synchronized(this) {
代码语言:txt复制 //放入等待队列
代码语言:txt复制 readyAsyncCalls.add(call)
代码语言:txt复制 // Mutate the AsyncCall so that it shares the AtomicInteger of an existing running call to
代码语言:txt复制 // the same host.
代码语言:txt复制 if (!call.call.forWebSocket) {
代码语言:txt复制 val existingCall = findExistingCallWithHost(call.host)
代码语言:txt复制 if (existingCall != null) call.reuseCallsPerHostFrom(existingCall)
代码语言:txt复制 }
代码语言:txt复制 }
代码语言:txt复制 //推进执行
代码语言:txt复制 promoteAndExecute()
代码语言:txt复制 }
代码语言:txt复制//将readyAsyncCalls中合格的请求过渡升级到runningAsyncCalls中
代码语言:txt复制private fun promoteAndExecute(): Boolean {
代码语言:txt复制 this.assertThreadDoesntHoldLock()
代码语言:txt复制 val executableCalls = mutableListOf<AsyncCall>()
代码语言:txt复制 val isRunning: Boolean
代码语言:txt复制 synchronized(this) {
代码语言:txt复制 val i = readyAsyncCalls.iterator()
代码语言:txt复制 while (i.hasNext()) {
代码语言:txt复制 val asyncCall = i.next()
代码语言:txt复制 if (runningAsyncCalls.size >= this.maxRequests) break // Max capacity.//运行最大64
代码语言:txt复制 if (asyncCall.callsPerHost.get() >= this.maxRequestsPerHost) continue // Host max capacity.每个主机最大5
代码语言:txt复制 i.remove()
代码语言:txt复制 asyncCall.callsPerHost.incrementAndGet()
代码语言:txt复制 executableCalls.add(asyncCall)
代码语言:txt复制 runningAsyncCalls.add(asyncCall)
代码语言:txt复制 }
代码语言:txt复制 isRunning = runningCallsCount() > 0
代码语言:txt复制 }
代码语言:txt复制 for (i in 0 until executableCalls.size) {
代码语言:txt复制 val asyncCall = executableCalls[i]
代码语言:txt复制 asyncCall.executeOn(executorService)
代码语言:txt复制 }
代码语言:txt复制 return isRunning
代码语言:txt复制 }
上面的流程主要是将我们的异步任务放入队列中 并且将可以运行的任务开启运行
RealCall.executeOn()
代码语言:txt复制fun executeOn(executorService: ExecutorService) {
代码语言:txt复制 client.dispatcher.assertThreadDoesntHoldLock()
代码语言:txt复制 var success = false
代码语言:txt复制 try {
代码语言:txt复制 //将当前Runnable放到线程池中运行
代码语言:txt复制 executorService.execute(this)
代码语言:txt复制 success = true
代码语言:txt复制 } catch (e: RejectedExecutionException) {
代码语言:txt复制 val ioException = InterruptedIOException("executor rejected")
代码语言:txt复制 ioException.initCause(e)
代码语言:txt复制 noMoreExchanges(ioException)
代码语言:txt复制 responseCallback.onFailure(this@RealCall, ioException)
代码语言:txt复制 } finally {
代码语言:txt复制 if (!success) {
代码语言:txt复制 client.dispatcher.finished(this) // This call is no longer running!
代码语言:txt复制 }
代码语言:txt复制 }
代码语言:txt复制 }
代码语言:txt复制override fun run() {
代码语言:txt复制 threadName("OkHttp ${redactedUrl()}") {
代码语言:txt复制 var signalledCallback = false
代码语言:txt复制 timeout.enter()
代码语言:txt复制 try {
代码语言:txt复制 //终于到这篇文章的重头戏了
代码语言:txt复制 val response = getResponseWithInterceptorChain()
代码语言:txt复制 signalledCallback = true
代码语言:txt复制 responseCallback.onResponse(this@RealCall, response)
代码语言:txt复制 } catch (e: IOException) {
代码语言:txt复制 if (signalledCallback) {
代码语言:txt复制 // Do not signal the callback twice!
代码语言:txt复制 Platform.get().log("Callback failure for ${toLoggableString()}", Platform.INFO, e)
代码语言:txt复制 } else {
代码语言:txt复制 responseCallback.onFailure(this@RealCall, e)
代码语言:txt复制 }
代码语言:txt复制 } catch (t: Throwable) {
代码语言:txt复制 cancel()
代码语言:txt复制 if (!signalledCallback) {
代码语言:txt复制 val canceledException = IOException("canceled due to $t")
代码语言:txt复制 canceledException.addSuppressed(t)
代码语言:txt复制 responseCallback.onFailure(this@RealCall, canceledException)
代码语言:txt复制 }
代码语言:txt复制 throw t
代码语言:txt复制 } finally {
代码语言:txt复制 client.dispatcher.finished(this)
代码语言:txt复制 }
代码语言:txt复制 }
代码语言:txt复制 }
代码语言:txt复制 }
我们知道OkHttp采用了拦截链模式 看一下何为拦截器模式
借用一下大佬的图(懒得画图了