Ich habe heute ein Upgrade auf Android Studio 3.1 durchgeführt, das anscheinend einige weitere Flusenprüfungen hinzugefügt hat. Eine dieser Flusenprüfungen betrifft einmalige RxJava2- subscribe()
Aufrufe, die nicht in einer Variablen gespeichert sind. Zum Beispiel, um eine Liste aller Spieler aus meiner Raumdatenbank zu erhalten:
Single.just(db)
.subscribeOn(Schedulers.io())
.subscribe(db -> db.playerDao().getAll());
Das Ergebnis ist ein großer gelber Block und dieser Tooltip:
Das Ergebnis von
subscribe
wird nicht verwendet
Was ist die beste Vorgehensweise für solche One-Shot-Rx-Anrufe? Soll ich das Disposable
und dispose()
auf vollständig halten? Oder soll ich einfach @SuppressLint
weitermachen?
Dies scheint nur RxJava2 ( io.reactivex
) zu betreffen , RxJava ( rx
) hat diese Flusen nicht.
android
android-studio
rx-java2
lint
android-studio-3.1
Michael Dodd
quelle
quelle
Disposable
at-Member-Bereich fest und rufe an,dispose()
wenn die Single fertig ist, aber es scheint unnötig umständlich. Ich bin gespannt, ob es dafür bessere Möglichkeiten gibt.Antworten:
Die IDE weiß nicht, welche potenziellen Auswirkungen Ihr Abonnement haben kann, wenn es nicht entsorgt wird, und behandelt es daher als potenziell unsicher. Beispielsweise kann Ihr
Single
Anruf einen Netzwerkanruf enthalten, der zu einem Speicherverlust führen kann, wenn Ihr AnrufActivity
während der Ausführung abgebrochen wird.Eine bequeme Möglichkeit, eine große Menge von
Disposable
s zu verwalten, ist die Verwendung eines CompositeDisposable . Erstellen Sie einfach eine neueCompositeDisposable
Instanzvariable in Ihrer umschließenden Klasse und fügen Sie dann alle Ihre Disposables zum CompositeDisposable hinzu (mit RxKotlin können Sie einfachaddTo(compositeDisposable)
alle Ihre Disposables anhängen ). Wenn Sie mit Ihrer Instanz fertig sind, rufen Sie schließlich aufcompositeDisposable.dispose()
.Dadurch werden die Flusenwarnungen entfernt und sichergestellt, dass Sie
Disposables
ordnungsgemäß verwaltet werden.In diesem Fall würde der Code folgendermaßen aussehen:
quelle
error: cannot find symbol method addTo(CompositeDisposable)
erhalte einen Kompilierungsfehler mit "rxjava: 2.1.13". Woher kommt diese Methode? (RxSwift oder RxKotlin, nehme ich an)In dem Moment, in dem die Aktivität zerstört wird, wird die Liste der Einwegartikel gelöscht und wir sind gut.
quelle
Sie können DisposableSingleObserver abonnieren :
Falls Sie ein
Single
Objekt direkt entsorgen müssen (z. B. bevor es ausgegeben wird), können Sie eine Methode implementierenonSubscribe(Disposable d)
, um das Objekt abzurufen und zu verwendenDisposable
Referenz .Sie können die
SingleObserver
Schnittstelle auch selbst realisieren oder andere untergeordnete Klassen verwenden.quelle
Wie vorgeschlagen, können Sie einige globale verwenden
CompositeDisposable
Ergebnis hinzufügen, um das Ergebnis des Abonnementvorgangs hinzuzufügen.Die RxJava2Extensions- Bibliothek enthält nützliche Methoden zum automatischen Entfernen von erstellten Einwegartikeln nach
CompositeDisposable
Abschluss. Siehe subscribeAutoDispose Abschnitt .In Ihrem Fall könnte es so aussehen
quelle
Sie können Uber AutoDispose und rxjava verwenden
.as
Stellen Sie sicher, dass Sie verstehen, wann Sie sich mit dem ScopeProvider abmelden.
quelle
Immer wieder komme ich auf die Frage zurück, wie Abonnements korrekt entsorgt werden können, und insbesondere auf diesen Beitrag. In mehreren Blogs und Vorträgen wird behauptet, dass ein fehlgeschlagener Anruf
dispose
zwangsläufig zu einem Speicherverlust führt, was meiner Meinung nach eine zu allgemeine Aussage ist. Nach meinem Verständnis ist die Flusenwarnung, dass das Ergebnis nicht gespeichertsubscribe
werden soll, in einigen Fällen kein Problem, da:Da ich Flusenwarnungen nicht unterdrücken möchte, habe ich kürzlich begonnen, das folgende Muster für Fälle mit einer synchronen beobachtbaren Größe zu verwenden:
Ich würde mich für Kommentare dazu interessieren, unabhängig davon, ob es sich um eine Bestätigung der Richtigkeit oder die Entdeckung einer Lücke handelt.
quelle
Es gibt eine andere Möglichkeit, die darin besteht, die manuelle Verwendung von Einwegartikeln zu vermeiden (Abonnements hinzufügen und entfernen).
Sie können ein Observable definieren und dieses Observable empfängt den Inhalt von einem SubjectBehaviour (falls Sie RxJava verwenden). Und indem Sie das Beobachtbare an Ihre LiveData weitergeben , sollte das funktionieren. Schauen Sie sich das nächste Beispiel anhand der ersten Frage an:
quelle
Wenn Sie sicher sind, dass Einwegartikel korrekt behandelt werden, z. B. mit dem Operator doOnSubscribe (), können Sie dies zu Gradle hinzufügen:
quelle
@SuppressLint("CheckResult")
nur die Methode unterdrücken .