OkHttp_3.12.0源碼分析

OkHttp_3.12.0源碼分析

基于OkHttp:3.12.0:https://github.com/square/okhttp/tree/okhttp_3.12.x

RTFSC

Read The Fucking Source Code

流程分析

  1. 用戶層面調(diào)用形式:
OkHttpClient#newCall(new Request())#enquenue(new Callback(){})

  1. OkHttpClient#newCall(new Request()):OkHttpClient根據(jù)client、request創(chuàng)建RealCall,RealCall里面包含所有請(qǐng)求的各種配置信息:攔截器、請(qǐng)求連接、調(diào)度器Dispatcher、ConnectionPool等
//OkHttpClient
@Override public Call newCall(Request request) {
    return RealCall.newRealCall(this, request, false /* for web socket */);
  }
  1. RealCall#enqueue(new Callback(){}):
    1. 通過(guò)RealCall中的client間接獲取Dispatcher--維護(hù)一個(gè)線程池、readyAsyncCalls、runningAsyncCalls、runningSyncCalls三個(gè)請(qǐng)求隊(duì)列。
    2. Dispatcher的enqueue會(huì)把當(dāng)前的responseCallback包裝成AsyncCall的形式放入readyAsyncCalls隊(duì)列中,注意AsyncCall實(shí)現(xiàn)了Runnable接口。
//RealCall
@Override public void enqueue(Callback responseCallback) {
     //其它信息...    
     client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }
  
// Dispatcher    
 void enqueue(AsyncCall call) {
    synchronized (this) {
         readyAsyncCalls.add(call);
        }
        promoteAndExecute();
    } 
  1. Dispatcher#promoteAndExecute:這一步會(huì)遍歷readyAsyncCalls把準(zhǔn)備隊(duì)列中的AsyncCall放到runningAsyncCalls運(yùn)行隊(duì)列中;同時(shí)放到立馬執(zhí)行的一個(gè)列表中:executableCalls。這里一些額外的判斷是:,請(qǐng)求是否超過(guò)了最大請(qǐng)求數(shù)maxRequests,同一個(gè)host是否大于maxRequestsPerHostmaxRequests。
    //Dispatcher
    private boolean promoteAndExecute() {
        //...
        List<AsyncCall> executableCalls = new ArrayList<>();
        //偽代碼...
        if(滿足一定條件){executableCalls.addAll(readyAsyncCalls)}
    
        for (int i = 0, size = executableCalls.size(); i < size; i++) {
          AsyncCall asyncCall = executableCalls.get(i);
          asyncCall.executeOn(executorService());
        }
    
        return isRunning;
      }
  1. AsyncCall#executeOn(executorService()):

    1. AsyncCall#executeOn(ExecutorService):通過(guò)線程池執(zhí)行當(dāng)前對(duì)象,會(huì)調(diào)用上層NamedRunnable的run()方法。重點(diǎn):這里完成線程切換邏輯,因?yàn)橄旅婢鸵_始去執(zhí)行耗時(shí)操作。
    2. NamedRunnable#run方法會(huì)調(diào)用execute(),具體邏輯在子類AsyncCall實(shí)現(xiàn)。
    3. AsyncCall#execute()是真正獲取Response值、把值回調(diào)給responseCallback的步驟。
   //AsyncCall 
   void executeOn(ExecutorService executorService) {
       //...
       executorService.execute(this);//這里會(huì)調(diào)用父類的run方法
       //...
   }
    //NamedRunnable, AsyncCall的父類  
    public abstract class NamedRunnable implements Runnable {
      //...    
      @Override public final void run() {
        //...
        execute();
      }
      //子類AsyncCall做對(duì)應(yīng)實(shí)現(xiàn)
      protected abstract void execute();
    }        
        
   #AsyncCall
   @Override protected void execute() {
       boolean signalledCallback = false;
       timeout.enter();
       try {
       //關(guān)鍵,去獲取response對(duì)象,真正的耗時(shí)也就在這
       Response response = getResponseWithInterceptorChain();
       if (retryAndFollowUpInterceptor.isCanceled()) {
           signalledCallback = true;
           //失敗,請(qǐng)求被取消
            responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
       } else {
           signalledCallback = true;
           //成功請(qǐng)求,拿去結(jié)果回調(diào)
           responseCallback.onResponse(RealCall.this, response);
           }
        } catch (IOException e) {
           e = timeoutExit(e);
           if (signalledCallback) {
             // Do not signal the callback twice!
             Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
           } else {
             eventListener.callFailed(RealCall.this, e);
             //失敗,回調(diào)
             responseCallback.onFailure(RealCall.this, e);
       }
         } finally {
           //完整結(jié)束當(dāng)前請(qǐng)求,做一些收尾操作
           client.dispatcher().finished(this);
         }
       }
     }
     
  1. RealCall#getResponseWithInterceptorChain:
    1. RealCall#getResponseWithInterceptorChain會(huì)把用戶自定義的攔截器、系統(tǒng)級(jí)別的攔截器放到list中組裝好,給一個(gè)new RealInterceptorChain。這里需要注意攔截器加入的順序,用戶攔截器優(yōu)先級(jí)最高->系統(tǒng)一些中間攔截->最后網(wǎng)絡(luò)請(qǐng)求。
    2. RealInterceptorChain#proceed在這里會(huì)構(gòu)造一個(gè)新的RealInterceptorChain:next,注意新的RealInterceptorChain中index+1;另外根據(jù)當(dāng)前的index取得當(dāng)前攔截器,執(zhí)行攔截器中唯一的方法intercept(next),具體執(zhí)行的哪一個(gè)呢,就看上層實(shí)現(xiàn)的是哪一個(gè)具體實(shí)現(xiàn)。
    3. 我們隨便看一個(gè)實(shí)現(xiàn),假如BridgeInterceptor:會(huì)在BridgeInterceptor中執(zhí)行BridgeInterceptor相關(guān)的實(shí)現(xiàn),最關(guān)鍵的會(huì)執(zhí)行chain.proceed(requestBuilder.build()),注意Chain是上一個(gè)創(chuàng)建的RealInterceptorChain,所以又跑到了第二步,同時(shí)index這個(gè)時(shí)候已經(jīng)+1,如此完成遞歸操作!
    4. 經(jīng)過(guò)2、3兩步,通過(guò)迭代操作,完整所有攔截器的執(zhí)行。至于說(shuō)網(wǎng)絡(luò)請(qǐng)求、緩存、重試、日志等等核心包括外圍功能,全部通過(guò)攔截器實(shí)現(xiàn),并且責(zé)任分明,高度解耦合,實(shí)現(xiàn)方式:責(zé)任鏈模式。
#RealCall
Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    //用戶添加的自定義攔截器
    interceptors.addAll(client.interceptors());
    //重試
    interceptors.add(retryAndFollowUpInterceptor);
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    interceptors.add(new CacheInterceptor(client.internalCache()));
    interceptors.add(new ConnectInterceptor(client));
    if (!forWebSocket) {
      interceptors.addAll(client.networkInterceptors());
    }
    interceptors.add(new CallServerInterceptor(forWebSocket));

    Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
        originalRequest, this, eventListener, client.connectTimeoutMillis(),
        client.readTimeoutMillis(), client.writeTimeoutMillis());

    return chain.proceed(originalRequest);
  }
  
#RealInterceptorChain
@Override public Response proceed(Request request) throws IOException {
    return proceed(request, streamAllocation, httpCodec, connection);
  }

  public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
      RealConnection connection) throws IOException {
    //...
    
    //注意這里又構(gòu)造了一個(gè)RealInterceptorChain,重點(diǎn)index+1
    RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,
        connection, index + 1, request, call, eventListener, connectTimeout, readTimeout,
        writeTimeout);
        
    //取當(dāng)前index對(duì)應(yīng)的攔截器
    Interceptor interceptor = interceptors.get(index);
    //執(zhí)行取到的攔截器
    Response response = interceptor.intercept(next);
    
    //...
    return response;
  }

# BridgeInterceptor
@Override public Response intercept(Chain chain) throws IOException {
    //根據(jù)上游chain繼續(xù)處理當(dāng)前攔截器。注意:chain的源頭:RealInterceptorChain#proceed中創(chuàng)建的next,一個(gè)新的RealInterceptorChain
    Request userRequest = chain.request();
    Request.Builder requestBuilder = userRequest.newBuilder();

    //各種邏輯,跳過(guò)只看核心...
    
    //核心,這里又回到了RealInterceptorChain#proceed
    Response networkResponse = chain.proceed(requestBuilder.build());

    //后續(xù)邏輯...

    return responseBuilder.build();
  }

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容