- # okhttp源碼 筆記?
## call.enqueue的時候發(fā)生了什么删铃??
首先要知道該call是由okHttpClient.newCall(request)返回的RealCall
來看一下 call.enqueue的源碼:
? ? public void enqueue(Callback responseCallback) {
?????synchronized (this) {
????????? if (executed) throw new IllegalStateException("Already Executed");? ? ?
? ? ? ? ? executed = true; //如果該請求已經(jīng)發(fā)出,就會拋出一個已經(jīng)存在錯誤
? ? }
? ? ? captureCallStackTrace();//捕捉Call棧
? ? ? eventListener.callStart(this); //通知事件監(jiān)聽,該請求已經(jīng)開始了
? ? ? client.dispatcher().enqueue(new AsyncCall(responseCallback)); //將該請求分發(fā)到隊列中,并且是異步的Call
? ? ?}
### 其中比較難懂的應該是captureCallStackTrace()這個方法潮太,來看一下 它是干什么的
private void captureCallStackTrace() {
? ? ? ?Object callStackTrace = Platform.get().getStackTraceForCloseable("response.body().close()"); //捕獲已經(jīng)被關閉的response 處于的棧
????? ?retryAndFollowUpInterceptor.setCallStackTrace(callStackTrace); //重新請求與重定向的攔截器,設置Call棧的追蹤器挟伙,有了這個追蹤器真竖,該interceptor就可以通過對Call棧內(nèi)不同的情況進行不同處理
? ? }
接著是 client.dispatcher().enqueue(new AsyncCall(responseCallback)); //client將本次連接分發(fā)到相應的連接池中并且異步請求
????dispatcher()之后返回的是一個Dispatcher對象,那么這個對象是干什么的呢详幽?
????**Dispatcher 是一個事件分發(fā)者**筛欢,用于將每個請求放置到請求池以及相應的線程中去**其中OkHttp的并發(fā)最大請求數(shù)量為64個浸锨,最大主機數(shù)量為5個**
????????本節(jié)不討論okhttp的分發(fā)策略,只討論call.enqueue到底做了什么
????????在該請求處于相應的請求池中版姑,隨后執(zhí)行的就是enqueue方法柱搜,
synchronized void enqueue(AsyncCall call) {
? ? ?if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) ????{
? ? ?runningAsyncCalls.add(call);//如果當前的請求數(shù)量與主機數(shù)均未超出最大數(shù)量,就在添加到運行池中
? ? ?executorService().execute(call);//通過**executorService()**執(zhí)行call剥险。
? ? } else {
? ? readyAsyncCalls.add(call);//不然就添加到等待池中
? ? }?
? }
可以從源碼中發(fā)現(xiàn)聪蘸,enqueue()是將本次請求加入到請求隊列中,如果請求數(shù)達到了最大請求數(shù)炒嘲,則將本次請求加入到準備隊列中宇姚,并且通過了一個Service來管理call的生命
**executorService()**
這個服務是用來管理call的,可以shoutdown服務夫凸;或者添加服務但是不執(zhí)行浑劳,在特定的時間執(zhí)行。本次不詳細分析
隨后的就是在enqueue中要傳入的型參**AsyncCal**l
### AsyncCall 則是OkHttp封裝的異步回掉夭拌,用于返回Response
#### 通過 該類中的execute()返回具體的Response下面來看一下該方法的源碼
? ? ? @Override protected void execute() {
? ? ?????????boolean signalledCallback = false; //用于判斷請求是否成功
? ? ? ? try {
? ? ? ????????? Response response = getResponseWithInterceptorChain();
? ? ? ? if (retryAndFollowUpInterceptor.isCanceled()) {
? ? ? ? ? ? ? ? signalledCallback = true;
????????? ? ? ? responseCallback.onFailure(RealCall.this, new IOException("Canceled"));//如果請求成功魔熏,但是服務器解析失敗,并且返回了錯誤code鸽扁,那么就會拋一個錯誤:本次請求取消
? ? ? } else {
????? ? ? ? ?signalledCallback = true;
? ? ?responseCallback.onResponse(RealCall.this, response); //如果請求成功蒜绽,并且code為200,那么就會返回這個response
? ? ? ? }
? ? ? } catch (IOException e) {
? ? ? ?if (signalledCallback) {
? ? ? ? ? // Do not signal the callback twice!
? ? ? ? ?Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
? ? ? ? } else {
? ? ? ?eventListener.callFailed(RealCall.this, e);//事件監(jiān)聽:請求失敗?????
? ? ? ? responseCallback.onFailure(RealCall.this, e);//調(diào)用responseCallback的onFailure方法
? ? ? ? }
? ? ? } finally {
? ? ? client.dispatcher().finished(this);//通知事件分發(fā)器結束本次請求
? ? ? }
? ? ?}
? ? }
所以桶现,call.equeue之后躲雅,Okhttp會捕捉本次request所處于的棧,然后通知事件監(jiān)聽器請求開始骡和,請求開始之后相赁,okhttp的事件分發(fā)器就會將本次請求分發(fā)到相應的線程池中,最后根據(jù)請求結果異步回掉response
如果有錯慰于,希望大家指正Eタ啤!第一次看源碼