okhttp请求流程简单分析

作为google主推的网络请求框架okhttp,很多时候我们都是拿过来直接用,对于内部怎么做到的却不知道。如果知道内部的流程,在对扩展和处理一些bug就容易多了,接下来就简单分析下请求流程
首选我们创建一个okhttpclient

//  使用默认的配置
   val client = OkHttpClient.Builder().build()

接下来我们分别以get请求和post请求讲解

初始化我们的url请求信息

//  这个是配置操作 ,也可以直接对url写死的
   val httpurl = HttpUrl.Builder()
            .scheme("https")
            .host("www.baidu.com")
            // 添加路径
            .addPathSegments("mobileapi2")
            .addPathSegments("index.php")
            // 添加参数
            .addQueryParameter("act", "goods")
            .addQueryParameter("op", "goods_list")
            .build()
           //  最后的url就像这样  https//"www.baidu.com/mobileapi2/index.php?act=goods&op=goods_list

如果是get请求可以接着使用addQueryParameter方法添加我们需要的参数,如果是post请求我们就需要在创建一个请求体Body

        val builder = FormBody.Builder()
        builder.addEncoded("page", "10")
        builder.addEncoded("curpage", "1")
        val formBody = builder.build()

然后通过创建request构建我们的一个请求

   val request = Request.Builder()
            .url(httpurl) // 配置的url信息
          //  .get()  get请求
          //  .post(formBody)  post请求  post独有的请求体
            .build()

最后通过

// 异步
 client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
            }

            override fun onResponse(call: Call, response: Response) {
            }
        })
// 同步
client.newCall(request).execute()

就完成我们的请求了,那么内部怎么处理的呢?
我们首选看下newCall方法做了什么

// 创建了一个新的RealCall ,RealCall继承了Call    第一个参数是我们的client
  override fun newCall(request: Request): Call = RealCall(this, request, forWebSocket = false)

我们接着看RealCall内部的enqueue方法

// 我们的client在构建的时候,默认初始化了dispatcher,dispatcher内部维护了线程池和请求队列
 client.dispatcher.enqueue(AsyncCall(responseCallback))

创建一个AsyncCall。这个AsyncCall其实是一个Runnable,可以看作是我们请求的一个任务,dispatcher.enqueue方法就是将任务放入等待队列中

// dispatcher类
 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()
  }
// dispatcher类
  private fun promoteAndExecute(): Boolean {
    this.assertThreadDoesntHoldLock()

    val executableCalls = mutableListOf()
    val isRunning: Boolean
    synchronized(this) {
      val i = readyAsyncCalls.iterator()
      while (i.hasNext()) {
        val asyncCall = i.next()
          //  请求数 大于等于64 结束循环
        if (runningAsyncCalls.size >= this.maxRequests) break // Max capacity.
        // 同一个host大于等于5 结束循环
        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类
  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!
        }
      }
    }

然后就会执行AsyncCall的run方法

   override fun run() {
      threadName("OkHttp ${redactedUrl()}") {
        var signalledCallback = false
        timeout.enter()
        try {
        // 使用默认提供的五大拦截器,对重定向,配置请求头,缓存,建立连接,对服务进行网络调用
      
          val response = getResponseWithInterceptorChain()
          signalledCallback = true
          // Callback将我们得到的响应体回调
          responseCallback.onResponse(this@RealCall, response)
        } catch (e: IOException) {
          if (signalledCallback) {
            // Do not signal the callback twice!
            Platform.get().log("Callback failure for ${toLoggableString()}", Platform.INFO, e)
          } else {
          // 错误信息回调
            responseCallback.onFailure(this@RealCall, e)
          }
        } catch (t: Throwable) {
          cancel()
          if (!signalledCallback) {
            val canceledException = IOException("canceled due to $t")
            canceledException.addSuppressed(t)
            responseCallback.onFailure(this@RealCall, canceledException)
          }
          throw t
        } finally {
          client.dispatcher.finished(this)
        }
      }
    }
  }

至此我们就完成了post请求
get请求流程比post就简单了

// newCall和post一样 ,主要看execute
 val  response= client.newCall(request).execute()
//  
override fun execute(): Response {
    check(executed.compareAndSet(false, true)) { "Already Executed" }

    timeout.enter()
    callStart()
    try {
      // this 就是call  通过我们的dispatcher将任务放入到 runningSyncCalls队列中
      client.dispatcher.executed(this)
      // 通过默认的五大拦截器 就得到我们服务的响应数据
      return getResponseWithInterceptorChain()
    } finally {
      client.dispatcher.finished(this)
    }
  }

你可能感兴趣的:(okhttp,android)