2015-12-19 15 views
7

私は、OkHttp 2.7.0でRetrofit 2-beta2を使用しています。Retrofit 2/OkHttp:実行中のリクエストをすべてキャンセルします。

私はRetrofit .client()メソッドを使用していますし、それが要求を実行しているすべてをキャンセルし、私はそれがcancel(Object tag)方法だ呼んでいるが、要求はまだ実行し続けると私は応答を取得レトロフィットからOkHttpClientオブジェクトを取得します。

クライアントのDispatcherでも、getQueuedCallCount()getRunningCallCount()は、cancel()を呼び出した後に0を返します。

これが機能するために必要なことは他にありますか?あるいは、それはOkHttpのバグでしょうか?

回避策として、クライアントのExecutorServiceshutdownNow()と電話していますが、私はよりクリーンなソリューションを希望します。

+0

ソースコードを調べた後に、なぜこれが機能しないのか理解できました。インターセプタを使って 'Request'にタグを設定しているので、新しい' Request'オブジェクトを作成しています。 'Cancel()'が 'Dispatcher'のリクエストキューに存在しているので、元の' Request'がまだタグセットを持っていないので、 'OkHttpClient.cancel(Object tag)'は何もしません。 Retrofitは元の 'Request'オブジェクトにタグを設定するメソッドやインタフェースを公開していないようです。 –

答えて

15

更新:cancelAll()メソッドを持つDispatcherを使用すると、これはOkHttp 3で実現する方がずっと簡単です。ディスパッチャはOkHttpClient.dispatcher()から返されます。

旧ソリューション:これを行うには 唯一の方法は、(私が見つけることができること)OkHttpClientのサブクラスを作成して、レトロフィットしていることを使用することです。

class OkHttpClientExt extends OkHttpClient { 
    static final Object TAG_CALL = new Object(); 

    @Override 
    public Call newCall(Request request) { 
     Request.Builder requestBuilder = request.newBuilder(); 
     requestBuilder.tag(TAG_CALL); 
     return super.newCall(requestBuilder.build()); 
    } 
} 

次の行は、タグTAG_CALLを持つすべての要求を取り消します。上記のクラスはすべてのリクエストにTAG_CALLを設定するので、すべてのリクエストはキャンセルされます。

retrofit.client().cancel(OkHttpClientExt.TAG_CALL); 
+1

OkHttpClientを拡張するのではなく、リクエストごとにRequestInterceptorを追加してタグを追加するだけです。 – Matthew

+5

@Matthewはい、 'Interceptor'でタグを設定するとうまくいくでしょう。しかし、OkHttp 3では、 'Dispatcher'がタグに関係なくすべてのリクエストをキャンセルする' cancelAll() 'メソッドを提供するので、これはもう必要ありません。 –

+2

'Dispatcher'クラスを認識していませんでした。とても役に立ちました! – Matthew

関連する問題