okhttp之RealCall.execute()流程介紹

轉載請以鏈接形式標明出處:
本文出自:103style的博客


base on 3.12.0


目錄

  • 前言
  • OkHttpClient.newCall(Request)
  • RealCall.execute()
  • RealInterceptorChain.proceed(request)
  • 小結

前言

前面我們對 OkHttpClientRequest 做了相關的介紹。

此時我們已經構建了 http客戶端http請求,接下來就好通過 http客戶端 來執行http請求。即先通過OkHttpClient.newCall(Request)構建RealCall,然後通過 RealCall.execute() 來執行請求。


OkHttpClient.newCall(Request)

通過下面的源碼我們知道 OkHttpClientnewCall 方法即通過 RealCall.newRealCall()構建了一個RealCall實例,將 OkHttpClientRequest 賦值給實例的成員變量. 以及初始化了攔截器 RetryAndFollowUpInterceptor.

//OkHttpClient
public Call newCall(Request request) {
    return RealCall.newRealCall(this, request, false );
}
//RealCall
private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    this.client = client;
    this.originalRequest = originalRequest;
    this.forWebSocket = forWebSocket;
    this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);
    this.timeout = new AsyncTimeout() {
        @Override protected void timedOut() {
            cancel();
        }
    };
    this.timeout.timeout(client.callTimeoutMillis(), MILLISECONDS);
}
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    // Safely publish the Call instance to the EventListener.
    RealCall call = new RealCall(client, originalRequest, forWebSocket);
    call.eventListener = client.eventListenerFactory().create(call);
    return call;
}

RealCall.execute()

public Response execute() throws IOException {
    ...
    try {
        client.dispatcher().executed(this);
        Response result = getResponseWithInterceptorChain();
        ...
    } catch (IOException e) {
        ...
    } finally {
        client.dispatcher().finished(this);
    }
}

通過上面的代碼我們知道是通過getResponseWithInterceptorChain();獲取到請求的結果。

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

getResponseWithInterceptorChain中依次添加了以下的攔截器,後面會具體介紹:

  • client.interceptors():我們通過OkhttpClient添加的自定義攔截器
  • retryAndFollowUpInterceptor:重試及重定向攔截器
  • BridgeInterceptor:橋接攔截器
  • CacheInterceptor:緩存攔截器
  • ConnectInterceptor:連接攔截器
  • client.networkInterceptors():網絡請求的攔截器
  • CallServerInterceptor:讀寫攔截器

然後將 request請求interceptors這個攔截器集合構建了一個 RealInterceptorChain.
然後通過RealInterceptorChain.proceed(originalRequest);返回請求結果。


RealInterceptorChain.proceed(request)

public Response proceed(...) throws IOException {
    if (index >= interceptors.size()) throw new AssertionError();
    calls++;
    ...
    RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,
            connection, index + 1, request, call, eventListener, connectTimeout, readTimeout,
            writeTimeout);
    Interceptor interceptor = interceptors.get(index);
    Response response = interceptor.intercept(next);
    ...
    return response;
}

我們可以看到這裏通過interceptor.intercept(next);獲取的請求結果。
我們先以RetryAndFollowUpInterceptor來介紹下。

public Response intercept(Chain chain) throws IOException {
    RealInterceptorChain realChain = (RealInterceptorChain) chain;
    ...
    response = realChain.proceed(request, streamAllocation, null, null);
    ...
}

看到上面代碼中的realChain.proceed(...);方法,是不是又回到了上面的RealInterceptorChain.proceed(request).

所以由此可知RealInterceptorChain.proceed(request)會 “依次” 去調用攔截器列表每個interceptors中的interceptor.intercept(next),如下圖:
RealCall.execute()

攔截器具體做了什麼操作呢?請聽下回分解。見 okhttp之五個攔截器的介紹


小結

通過上面的介紹,我們知道了:

  • OkHttpClient.newCall(Request)構建了一個 RealCall 實例。
  • RealCall.execute()通過添加一系列攔截器,然後依次執行攔截器的intercept(chain)方法,然後把響應結果再一層一層回傳到給 RealCall

以上

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章