2015-12-19 4 views
7

Ich benutze Retrofit 2-beta2 mit OkHttp 2.7.0.Nachrüstung 2/OkHttp: Alle laufenden Anfragen abbrechen

Um das OkHttpClient Objekt von Retrofit erhalte ich die Retrofit .client() Methode bin mit und alle abzubrechen es Anfragen läuft, ich rufe dann ist es cancel(Object tag) Methode, aber die Anfragen halten noch läuft und ich bekomme eine Antwort.

Selbst die 's getQueuedCallCount() und des Clients geben 0 zurück, nachdem cancel() aufgerufen wurde.

Gibt es noch etwas, das ich tun muss, damit dies funktioniert? Oder könnte es ein Fehler in OkHttp sein?

Als Workaround rufe ich shutdownNow() auf ExecutorService des Kunden, aber ich würde eine sauberere Lösung bevorzugen.

+0

Nach dem Durchlaufen des Quellcodes verstehe ich jetzt, warum das nicht funktioniert. Ich setze den Tag auf die "Anfrage" unter Verwendung eines Interceptors und erstelle daher ein neues "Anfrage" -Objekt. 'OkHttpClient.cancel (Object tag)' tut nichts, da die ursprüngliche 'Anfrage' (an der' cancel() 'aufgerufen wird, da sie in der Anfragewarteschlange des Dispatchers vorhanden ist) noch kein Tag gesetzt hat. Es scheint, dass Retrofit keine Methode oder Schnittstelle zur Verfügung stellt, um ein Tag auf das ursprüngliche "Request" -Objekt zu setzen. –

Antwort

15

UPDATE: Das ist jetzt viel einfacher, in OkHttp zu erreichen 3 von Dispatcher, der zu einer cancelAll() Methode hat. Der Dispatcher wird von OkHttpClient.dispatcher() zurückgegeben.

Alte Lösung: Der einzige Weg, dies zu tun (das ich finden kann) ist eine Unterklasse von OkHttpClient zu erstellen und das mit Retrofit verwenden.

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

Die folgende Zeile löscht alle Anfragen mit dem Tag TAG_CALL. Da die obige Klasse TAG_CALL auf alle Anfragen setzt, werden alle Anfragen abgebrochen.

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

Statt den OkHttpClient zu erweitern, können Sie einfach einen RequestInterceptor hinzufügen und Ihr Tag für jede Anfrage hinzufügen. – Matthew

+5

@Matthew Ja, das Setzen des Tags mit einem 'Interceptor' hätte auch funktioniert. Mit OkHttp 3 ist dies jedoch nicht mehr erforderlich, da "Dispatcher" die Methode 'cancelAll()' bereitstellt, die alle Anfragen unabhängig von Tags löscht. –

+2

War der 'Dispatcher'-Klasse nicht bekannt, sehr hilfreich! – Matthew