2017-11-03 2 views
0

Ich habe eine untere Leiste mit vier Registerkarten. Jede Registerkarte ist eine . Ich möchte alle Netzwerkanrufe stoppen, wenn der Benutzer zu einem anderen Fragment wechselt, also füge ich alle Observable Anrufe zu einem CompositeSubscription hinzu und ich melde mich von ihnen in onDestroyView() ab. Wenn der Benutzer das nächste Mal den Bildschirm betritt, scheitern alle Netzwerkanrufe (da ich mich abgemeldet habe), also möchte ich mich erneut anmelden.Wie kann ich Observables wiederbestellen

Ich bin nicht sicher, wie ich das tun soll: Irgendwie muss ich neu abonnieren, wenn onResume()/onViewAttached() für das Fragment aufgerufen wird. Ich benutze RxJava 1.

Edit: Ich habe ähnliche Fragen überprüft und ihre Antworten erwähnen cache und replay Operatoren, aber ich glaube nicht, dass das der Fall ist, weil sie fragen, auch die zuvor emittierten Elemente zu bekommen, während ich gerade Ich möchte wieder alle Netzwerkanrufe durchführen können.

Dies ist, wie ich für ein Netzwerk Anruf zu einem beobachtbaren bin abonnieren:

  subscriptions.add(remoteDataSource.getFeedMore(localDataSource.getFirstStoredId()) 
       .doOnNext(new Action1<FeedItemsRequestDetailsWrapper>() { 
        @Override 
        public void call(FeedItemsRequestDetailsWrapper wrapper) { 
         if (wrapper != null) { 
          localDataSource.saveFeed(wrapper.getFeedItemList()); 
          localDataSource.saveServerState(wrapper.getFeedRequestDetails()); 
         } 
        } 
       }) 
       .subscribeOn(schedulerProvider.io()) 
       .observeOn(schedulerProvider.mainThread()) 
       .subscribe(new Action1<FeedItemsRequestDetailsWrapper>() { 
        @Override 
        public void call(FeedItemsRequestDetailsWrapper wrapper) { 
         // call to View to update 
        } 
       })); 

Und wie ich abmelden:

@Override 
public void unsubscribe() { 
    if (subscriptions != null && subscriptions.hasSubscriptions()) { 
     subscriptions.unsubscribe(); 
    } 
} 

Beispiel Use Case: Benutzer Timeline Bildschirm eingibt, Benutzer ein anklickt Button und ein Netzwerkaufruf wird ausgeführt (modelliert als Observable in meiner Presenter-Klasse wie der Code, den ich oben gepostet habe). Dann verlässt der Benutzer diesen Bildschirm ( onDestroyView() wird aufgerufen und alle Abonnements sind abgemeldet). Einige Zeit später gibt der Benutzer den Bildschirm Timeline erneut ein und klickt auf die Schaltfläche.

Dies ist, wenn ich HTTP FAILED: java.io.IOException: Canceled bekomme, weil ich mich abgemeldet habe und ich erneut abonnieren möchte, damit ich den Netzwerkanruf ohne Fehler ausführen kann.

Dank

+0

Haben Sie 'clear' für' CompositeSubscription' rufen abbestellen? Wenn ja, müssen Sie mehr zeigen. – masp

+0

Ich habe die Frage mit etwas Code aktualisiert. – Mes

Antwort

1

aktualisieren

Wenn Sie in CompositeSubscrition abmelden rufen Sie nicht neue Abonnements, um es wieder hinzufügen können. Wenn Sie die gleiche zusammengesetzte Instanz erneut verwenden möchten, müssen Sie subscriptions.clear() aufrufen, oder Sie können eine neue Instanz erstellen, wenn das Fragment initialisiert wird.

Zurück

Das Wichtigste zuerst, wenn Sie von jedem beobachtbaren/Strom abmelden/fließfähige usw. Sie gonna die alle eingehenden Daten/Ereignisse verlieren.

Wenn Sie das neueste Ergebnis eines Abonnements erhalten möchten, dann sollten Sie es natürlich tun, bevor der Newsletter abbestellt wird.

Das Problem hier ist Ihre Abonnements sollte nicht von Fragment oder Activity Lebenszyklus abhängen, es sei denn, es ist vollständig fertig/zerstört. Wenn Sie wissen, dass Sie lange Anfragen haben, sollten Sie sie unter android.app.Service abonnieren.

Dann wird ein anderes Problem auftreten, das zwischen Services und Fragments/Activities hin und her kommuniziert.

Die einfache Lösung auf Ihrem Fall ist es, Sie ein BehaviourSubject in einer Singleton-Klasse erstellen können (besser Dagger zu verwenden, das model sowohl Fragment und Service zu injizieren). Dann in Ihrem Service abonnieren Sie Ihren lang laufenden Stream und veröffentlichen die nächsten Ereignisse zu diesem BehaviourSubject

BehaviourSubject speichert die zuletzt emittierten Daten. Wenn Sie das nächste Mal in Ihrem neu erstellten Fragment abonnieren, wird es mit dem letzten ausgegebenen Objekt beginnen.

Natürlich ist diese Antwort decken nur einen Anwendungsfall nach Ihren Wünschen Sie etwas anderes zu tun brauchen.

+0

Aber ich interessiere mich nicht wirklich für die letzten ausgestrahlten Daten. Ich möchte (wieder) nur das Observable abonnieren. – Mes

+0

@Mes Sie müssen subscriptions.clear() nicht .unsubscribe() aufrufen – Gunhan