これは...Excute()プロセスの紹介

5589 ワード

転載はリンク形式で出典を明記してください:本文は103 styleのブログから出ています
base on 3.12.0
目次
  • 前言
  • OkHttpClient.newCall(Request)
  • RealCall.execute()
  • RealInterceptorChain.proceed(request)
  • 小結
  • 前言
    先にOkHttpClientとRequestについて紹介しました.
    このとき、http およびhttp が構築され、http によってhttp が実行される.すなわち、OkHttpClient.newCall(Request)によってRealCallが構築され、その後、RealCall.execute()によって要求が実行される.
    OkHttpClient.newCall(Request) OkHttpClientnewCallの方法、すなわちRealCall.newRealCall()によってRealCallのインスタンスが構築され、OkHttpClientおよびRequestがインスタンスのメンバー変数に付与.ブロック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 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)は、以下の図:okhttp之RealCall.execute()流程介绍_第1张图片
    遮断器は具体的にどんな操作をしましたか?次回の分解を聞いてください.okhttpの5つのブロックの紹介を参照してください
    小結
    以上の紹介を通じて、私たちは知っています.
  • interceptorsは、interceptor.intercept(next)のインスタンスを構築する.
  • OkHttpClient.newCall(Request)は、一連のブロッキングを追加することによって、次いで、ブロッキングのRealCall方法を順次実行し、応答結果をRealCall.execute()にさらに1層ずつ返信する.

  • 以上