Abonnieren mit Vs abonnieren in RxJava2 (Android)?

Lesezeit: 8 Minuten

Benutzer-Avatar
bastami82

Wann sollte man die MethodescribeWith anstelle des einfachen Abonnements aufrufen? Und was ist der Anwendungsfall?

compositeDisposable.add(get()
    .observeOn(AndroidSchedulers.mainThread())
    .subscribeOn(Schedulers.io())
    .subscribe(this::handleResponse, this::handleError));

VS

   compositeDisposable.add(get()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
              //  .subscribe(this::handleResponse, this::handleError);
                .subscribeWith(new DisposableObserver<News>() {
                    @Override public void onNext(News value) {
                        handleResponse(value);
                    }

                    @Override public void onError(Throwable e) {
                        handleError(e);
                    }

                    @Override public void onComplete() {
                       // dispose here ? why? when the whole thing will get disposed later
                       //via  compositeDisposable.dispose();  in onDestroy();
                    }
                }));

Vielen Dank


Später hinzugefügt

Laut Dokumentation geben beide Einweg-SingleObserver-Instanzen zurück:

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final <E extends SingleObserver<? super T>> E subscribeWith(E observer) {
    subscribe(observer);
    return observer;
}

@SchedulerSupport(SchedulerSupport.NONE)
public final Disposable subscribe(final Consumer<? super T> onSuccess, final Consumer<? super Throwable> onError) {
    ObjectHelper.requireNonNull(onSuccess, "onSuccess is null");
    ObjectHelper.requireNonNull(onError, "onError is null");
    ConsumerSingleObserver<T> s = new ConsumerSingleObserver<T>(onSuccess, onError);
    subscribe(s);
    return s;
}

Dabei implementiert die ConsumerSingleObserver-Klasse SingleObserver und Disposable.

  • Dank @Simbatrons Antwort, um den spezifischen Anwendungsfall (nach dem, was ich verstanden habe) zusammenzufassen, ist, wenn Sie denselben Beobachter haben, den Sie an verschiedene Observable binden möchten, verwenden Sie “subscribeWith”. (damit mehrere Observables dieselbe Observer-Implementierung verwenden können). Bitte fügen Sie Ihren Kommentar hinzu, wenn Sie der Meinung sind, dass dies nicht der einzige Unterschied im Anwendungsfall ist

    – bastami82

    15. Juli 2017 um 8:03 Uhr

  • Ich frage mich dasselbe – meiner Meinung nach ist Ihr erstes Snippet viel sauberer mit der Verwendung von Lambdas usw. Also ja, es scheint, als ob der seltene Fall, dass Sie denselben Observer wiederverwenden möchten, das einzige Mal ist, dass Sie .subscribeWith() benötigen? Es ist seltsam, dass die Dokumente die überladene Variante von Subscribe nicht wirklich erwähnen, die das Disposable zurückgibt. Stattdessen weisen sie Sie nur darauf hin, das neue und unhandliche SubscribeWith() zu verwenden.

    – Verbrennungsanlage

    11. Oktober 2017 um 12:35 Uhr

Benutzer-Avatar
mmaarouf

Observable#subscribe-Erklärung:

In Ihrem ersten Code-Snippet:

.subscribe(this::handleResponse, this::handleError));

Sie verwenden tatsächlich eine der mehreren überladenen Observable#subscribe Methoden:

public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError)

Es gibt noch einen, der auch einen aufnimmt Action ausführen beiComplete:

public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
        Action onComplete) {

Und eine weitere Option ermöglicht es Ihnen, einfach eine zu übergeben Observer (HINWEIS: Void-Methode) (Bearbeiten 2 – diese Methode ist definiert in ObservableSourcedas ist die Schnittstelle, die Observable erweitert.)

public final void subscribe(Observer<? super T> observer)

Im zweiten Code-Snippet in Ihrer Frage haben Sie die subscribeWith Methode, die einfach die zurückgibt Observer Sie übergeben (aus Gründen der Bequemlichkeit / Zwischenspeicherung usw.):

public final <E extends Observer<? super T>> E subscribeWith(E observer)

Beobachter#onVollständige Erklärung:

Observer#onComplete wird aufgerufen, nachdem Observable alle Elemente im Stream ausgegeben hat. Aus dem Java-Dokument:

/**
 * Notifies the Observer that the {@link Observable} has finished sending push-based notifications.
 * <p>
 * The {@link Observable} will not call this method if it calls {@link #onError}.
 */
void onComplete();

Also zum Beispiel, wenn die get() in Ihren Code-Snippets zurückgegeben an Observable das mehrfach emittiert News Objekte, jeder wird in behandelt Observer#onNext. Hier können Sie jeden Artikel bearbeiten.

Nachdem sie alle verarbeitet wurden (und vorausgesetzt, dass kein Fehler aufgetreten ist), wird die onComplete wird angerufen. Hier können Sie alle zusätzlichen Aktionen ausführen, die Sie ausführen müssen (z. B. die Benutzeroberfläche aktualisieren), in dem Wissen, dass Sie alle verarbeitet haben News Objekte.

Damit ist nicht zu verwechseln Disposable#dispose die aufgerufen wird, wenn der beobachtbare Stream endet (complete/error), oder manuell von Ihnen, um die Beobachtung zu beenden (hier befindet sich die CompositeDisposable kommt herein, da es Ihnen hilft, alle Ihre zu entsorgen Disposables, die es sofort enthält).

Wenn in Ihrem Szenario die get() wird ein zurückgeben Observable die nur ein einzelnes Element ausgibt, dann statt einer Observableerwägen Sie die Verwendung von an io.reactivex.Single wo Sie nur das eine Element bearbeiten (in onSuccess) und muss keine angeben Action für onComplete 🙂

Bearbeiten: Antwort auf deinen Kommentar:

Allerdings kann ich SubscribeWith immer noch nicht verwenden. Sie sagten, es übergibt den Beobachter zum Caching usw., wohin geht es? auf komplett? und von dem, was ich verstanden habe, verbraucht “subscribeWith” nicht wirklich das Observable (oder Single), oder?

Zur weiteren Klärung der subscribeWith Erklärung, was ich meinte war, dass es Wille verbrauchen die Observer Objekt, das Sie an übergeben haben subscribeWith (genau wie die subscribe -Methode), aber es wird auch denselben Beobachter direkt an Sie zurücksenden. Zum Zeitpunkt des Verfassens dieses Artikels lautet die Implementierung vonscribeWith:

public final <E extends Observer<? super T>> E subscribeWith(E observer) {
    subscribe(observer);
    return observer;
}

Deswegen, subscribeWith kann austauschbar mit verwendet werden subscribe.

Können Sie einen Anwendungsfall von “subscribeWith” mit einem Beispiel geben? Ich denke, das wird die Frage vollständig beantworten

Das subscribeWith javadoc gibt das folgende Verwendungsbeispiel:

Observable<Integer> source = Observable.range(1, 10);
CompositeDisposable composite = new CompositeDisposable();

ResourceObserver<Integer> rs = new ResourceObserver<>() {
     // ...
};

composite.add(source.subscribeWith(rs));

Siehe hier die Verwendung von subscribeWith werde das gleiche zurückgeben ResourceObserver Objekt, das instanziiert wurde. Dies bietet den Komfort, das Abonnement durchzuführen und die hinzuzufügen ResourceObserver zum CompositeDisposable in einer Zeile (beachten Sie, dass ResourceObservable implementiert Disposable.)

Bearbeiten 2 Antwort auf den zweiten Kommentar.

source.subscribeWith(rs); source.subscribe(rs); beide geben die SingleObserver-Instanz zurück,

ObservableSource#subscribe(Observer <? super T> observer) nicht Rückkehr ein Observer. Es ist eine ungültige Methode (siehe HINWEIS unter der Beobachtbar#abonnieren Erklärung oben.) Während die Observable#subscribeWith TUT Gib die … wieder Observer. Wenn wir den Beispielverwendungscode mit neu schreiben würden ObservableSource#subscribe Stattdessen müssten wir es in zwei Zeilen wie folgt tun:

source.subscribe(rs); //ObservableSource#subscribe is a void method so nothing will be returned
composite.add(rs);

Während die Observable#subscribeWith Methode machte es uns bequem, das Obige in nur einer Zeile zu erledigen composite.add(source.subscribeWith(rs));

Es kann verwirrend werden mit all den überladenen Subscribe-Methoden, die etwas ähnlich aussehen, aber es gibt Unterschiede (von denen einige subtil sind). Ein Blick auf den Code und die Dokumentation hilft bei der Unterscheidung zwischen ihnen.


Bearbeiten 3 Ein weiteres Anwendungsbeispiel für „subscribeWith“.

Das subscribeWith -Methode ist nützlich, wenn Sie eine bestimmte Implementierung einer haben Observer die Sie vielleicht wiederverwenden möchten. Im obigen Beispielcode wurde beispielsweise eine spezifische Implementierung von bereitgestellt ResourceObserver im Abonnement, wodurch dessen Funktionalität geerbt wird, während Sie weiterhin onNext onError und onComplete behandeln können.

Ein weiteres Verwendungsbeispiel: für den Beispielcode in Ihrer Frage, was wäre, wenn Sie dasselbe Abonnement für die ausführen möchten get() Antwort an mehreren Stellen?

Anstatt die zu kopieren Consumer Implementierungen für onNext und onError über verschiedene Klassen hinweg, was Sie stattdessen tun können, ist eine neue Klasse für zB zu definieren.

//sample code..
public class GetNewsObserver extends DisposableObserver<News> {
    //implement your onNext, onError, onComplete.
    ....
}

Nun, wann immer Sie das tun get() Anfrage, können Sie einfach abonnieren, indem Sie Folgendes tun:

compositeDisposable.add(get()
    ...
    .subscribeWith(new GetNewsObserver()));

Sehen Sie, der Code ist jetzt einfach, Sie behalten die Trennung der Verantwortung für die Bearbeitung der Antwort bei und können diese jetzt wiederverwenden GetNewsObserver wo immer Sie wollen.

  • Vielen Dank für Ihre wertvollen Informationen. Sie haben mir geholfen, Disposing und OnComplete besser zu verstehen. Allerdings kann ich SubscribeWith immer noch nicht verwenden. Sie sagten, es übergibt den Beobachter zum Caching usw., wohin geht es? auf komplett? und von dem, was ich verstanden habe, verbraucht “subscribeWith” nicht wirklich das Observable (oder Single), oder? Also kannscribeWith nicht austauschbar mit der Subscribe-Methode verwendet werden. Können Sie einen Anwendungsfall von “subscribeWith” mit einem Beispiel geben? Ich denke, das wird die Frage vollständig beantworten. tnx

    – bastami82

    14. Juli 2017 um 7:51 Uhr

  • Antwort zur Antwort hinzugefügt 🙂

    – mmaarouf

    14. Juli 2017 um 15:29 Uhr

  • beziehen Sie sich auf Ihre letzte Edit-Antwort source.subscribeWith(rs); source.subscribe(rs); beide geben die SingleObserver-Instanz zurück, also haben Sie Recht, beide können austauschbar verwendet werden, dh composite.add(one | other) . aber warum sich jemand dafür entscheidet, einen über den anderen zu verwenden, bleibt mir unklar. Entschuldigung, wenn ich Ihren Punkt verpasst habe, aber ich sehe keinen bestimmten Anwendungsfall. Was ich damit meine, ist, dass wir in diesem Szenario “scribeWith” verwenden sollten und “subscribe” nicht liefert. TA

    – bastami82

    14. Juli 2017 um 16:02 Uhr

  • source.subscribe(rs); gibt keinen Beobachter zurück. Ich habe weitere Erklärungen im Abschnitt “Bearbeiten 2” der Antwort hinzugefügt.

    – mmaarouf

    14. Juli 2017 um 16:49 Uhr

  • Es hängt alles vom Anwendungsfall ab. Wenn Sie onNext, onError an einer Stelle abonnieren und eine eindeutige Implementierung bereitstellen möchten, wäre es sinnvoll, das #subscribe zu verwenden, das Lambdas aufnimmt. Andernfalls, wenn Sie allgemeinen Observer-Code in verschiedenen Klassen wiederverwenden müssen, wie das Beispiel, das ich in edit3 gegeben habe, oder wie das ResourceObservable-Beispiel aus dem Javadoc, dann können Sie #subscribeWith verwenden. Verwenden Sie, was das Problem am besten löst 🙂

    – mmaarouf

    11. Oktober 2017 um 13:13 Uhr


1119580cookie-checkAbonnieren mit Vs abonnieren in RxJava2 (Android)?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy