web-dev-qa-db-ja.com

OkHttp Interceptorでリクエストを停止する可能性はありますか?

私たちのアプリでは、1つの特別なケースに遭遇しました。App.specialFlag == trueの場合、コードからのリクエストをすべて停止する必要があります。そして、この状況での最善のアプローチは、次のようなリクエストをすべて停止する特別なInterceptorを含めることです。

if (App.specialFlag) {
    // Somehow stop request
} else {
    return chain.proceed(chain.request());
}

また、応答をRxJavaCallAdapterFactorysにラップするためにObservableを使用することに注意してください。

しかし、OkHttpインターセプターにリクエストを停止するメソッドはありません。

私たちは問題を解決する2つの方法を考え出しました:

a)すべてのリクエストをAPIで次のようにラップするための特別なApiService.classを作成します。

public Observable<User> getUserDetails() {
    if (App.specialFlag) {
        return Observable.just(null);
    }
    return api.getUserDetails();
}

しかし、それは醜く扱いにくい解決策だと思います。

b)InterceptorでRuntimeExceptionをスローし、APIを使用するすべての場所でキャッチします。

2番目のソリューションも適切ではありません。チェーンに多くのonErrorResumeNext演算子を含める必要があるためです。

誰かが知っているかもしれませんが、より「賢い」方法で状況を処理する方法.

前もって感謝します!

16

リクエストが(開始前に)実行されないようにする方法の1つは、 Response.Builder を追加して、試行したとおりに実行することです。

if (App.specialFlag) {
    return new Response.Builder()
                       .code(600) //Simply put whatever value you want to designate to aborted request.
                       .protocol(Protocol.HTTP_2)
                       .message("Dummy response")
                       .request(chain.request())
                       .build();
} else {
    return chain.proceed(chain.request());
}

EDIT 26/09/2019Bobstring によって言及された詳細で回答を更新

22
MatBos

受け入れられる回答 で欠けているのは、プロトコルとメッセージを指定する必要があることです。指定しないと、例外が発生します。このように見えます:

if (App.specialFlag) {
    return new Response.Builder()
                       .code(418) //Whatever code
                       .protocol(Protocol.HTTP_2)
                       .message("Dummy response")
                       .request(chain.request())
                       .build();
} else {
    return chain.proceed(chain.request());
}
22
Bobstring
  1. 制御ロジックスクリプトはhttpリクエストのみを行うために使用されるため、OkHttpの外部に置くことをお勧めします。リクエストをトリガーする方法と、UIを更新するためのレスポンスを処理する方法、それは気にする必要はありません。

  2. 必要に応じて、okhttp3.Interceptorから継承したクラスを作成し、関数のインターセプトをオーバーライドして、内部に制御ロジックスクリプトを配置できます。

    OkHttpClient client = new OkHttpClient.Builder()
       .connectTimeout(20, TimeUnit.SECONDS)
       .readTimeout(20, TimeUnit.SECONDS)
       .addInterceptor(new Interceptor())
       .build();
    
0
Da DUAN