Okhttp源码解析一

一个网络请求的流程框架?想了解 enqueue 怎么进行异步请求的

1 okhttpClient.newCall(request)  返回的是一个 RealCall 对象

2 然后执行realCall.enqueue  实际里边调用的是  dispatcher .enqueue  将网络请求放到后台线程执行

3  在后台线程  通过  getResponseWithInterceptorChain()  获取返回的响应response 放在callback 里回调回来

 

简单使用:

        var okhttpClient: OkHttpClient = OkHttpClient();
        var request: Request = Request.Builder()
                .url("https://square.github.io/okhttp/")
                .build();
        okhttpClient.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                TODO("Not yet implemented")
            }

            override fun onResponse(call: Call, response: Response) {
                TODO("Not yet implemented")
            }
        })

1 寻找切入点     enqueue   是个 call接口里的抽象方法        那么 返回来 看newCall怎么创建的     点击进去 newCall      进入了 

OkHttpClient.kt
  override fun newCall(request: Request): Call = RealCall(this, request, forWebSocket = false)

newCall  是创建 一个 RealCall对象     继续看 RealCall.的 enqueue          

RealCall  里维系了几个参数     

参数1  OkHttpClient  就是上边创建的OkHttpClient  通用配置都在这个类里 【比如超时时间啊什么的】

参数 2 Request originalRequest 请求 就是上边创建的请求,用来发起一个http请求 的条件 请求方法啊 http还是https什么的

这里有个 originalRequest 初始的request  ,什么是初始request  ,我们用来网络请求的request 不是最初传入的这个原始的request的 而是进过封装改变后的request ,最初被传入的就是这个初始的request

参数3   final boolean forWebSocket;     WebSocket也像http也是 应用层协议,,一般用不到  看看就行,,,适用频繁刷新数据     如股票软件

2  RealCall.kt   是Call 接口的实现    看RealCall 里enqueue   就可以       异步的网络请求

  override fun enqueue(responseCallback: Callback) {
    check(executed.compareAndSet(false, true)) { "Already Executed" }

    callStart()
    client.dispatcher.enqueue(AsyncCall(responseCallback))
  }

  2.1看 callStart方法 :作用 对http交互过程中进行监听的

  private fun callStart() {
    // 跟踪程序的错误  在出错的时候  做错误分析用的
    this.callStackTrace = Platform.get().getStackTraceForCloseable("response.body().close()")
    //  eventListener 是对http交互过程的监听器  比如http  header body开始发送,header body开始接收  链接的建立啊 都会监听,而这里是callStart 
    eventListener.callStart(this)
  }

2.2  看  client.dispatcher.enqueue(AsyncCall(responseCallback))  方法  里  dispatcher    是什么  dispatcher .enqueue方法干了什么AsyncCall是什么

追溯 dispatcher   发现 他是 Dispatcher的一个类   ,,这个 Dispatcher  实际上是做线程调度的,比如网络请求   同一时间 可能会有多个请求,,多个线程的管理 就需要线程调度,看Dispatcher里边实际上用的还是 Java里的ExecutorService  多线程管理的线程池的管理   

2,3看  dispatcher .enqueue

  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()
  }

实际上把 call  添加到  readyAsyncCalls  里 然后执行  promoteAndExecute()方法,,这个call是参数里 AsyncCall

2.4 看 readyAsyncCalls   是什么 点击进去

  // 把准备好要执行 还没执行  的call加入到这个双向队列里
  private val readyAsyncCalls = ArrayDeque<AsyncCall>()

然后再promoteAndExecute()里执行掉 

2.5 接下来看  promoteAndExecute   ,把符合条件的call 推举处理  然后执行。。符合的条件 1 需要还没执行过在readyAsyncCalls   里的  2 执行他不会导致超负载  

  private fun promoteAndExecute(): Boolean {
    this.assertThreadDoesntHoldLock()

    val executableCalls = mutableListOf<AsyncCall>()
    val isRunning: Boolean
    // 1 先挑选 符合条件的call,,readyAsyncCalls.iterator() 遍历出不会超负载的call挑出来
就promote  放在  executableCalls 集合里【可以执行的】
    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)
        // 把选出来的call也会放在 runningAsyncCalls  正在执行的call里 
        runningAsyncCalls.add(asyncCall)
      }
      isRunning = runningCallsCount() > 0
    }
    // 2 然后执行  存在这里可以执行的 call 集合  executableCalls
    for (i in 0 until executableCalls.size) {
      val asyncCall = executableCalls[i]
      // 对每个call执行 executeOn 
      asyncCall.executeOn(executorService)
    }

    return isRunning
  }

2.6 看 asyncCall.executeOn(executorService)  具体怎么执行的

    fun executeOn(executorService: ExecutorService) {
      client.dispatcher.assertThreadDoesntHoldLock()

      var success = false
      try {
        // 核心的 线程调用 开始执行 把runnable扔进去  这时候 切到后台线程
        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!
        }
      }
    }

executorService.execute(this)  传入的参数是this   接受类型是runnable    那么 asyncCall应该是实现了 runnable    接口的  所以找 asyncCall的run方法就行

2.7  看  asyncCall的run方法       

    override fun run() {
      threadName("OkHttp ${redactedUrl()}") {
        var signalledCallback = false
        timeout.enter()
        try {
          // 拿到返回的响应  
          val response = getResponseWithInterceptorChain()
          signalledCallback = true
          // responseCallback就是我们在enqueue  传入的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)
        }
      }
    }

找到了返回的响应

         val response = getResponseWithInterceptorChain()
          signalledCallback = true
          // responseCallback就是我们在enqueue  传入的callBack
          responseCallback.onResponse(this@RealCall, response)

这里 responseCallback  对应 当初传入的callBack

okhttpClient.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                TODO("Not yet implemented")
            }

            override fun onResponse(call: Call, response: Response) {
                TODO("Not yet implemented")
            }
        })

3 看 realCall  里  execute()  同步网络请求的方法    【一般不会调用】    

  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)
    }
  }

关键代码 还是  getResponseWithInterceptorChain()     直接 返回了  Response 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值