Wynik subskrypcji nie jest używany

Zaktualizowałem dziś do Android Studio 3.1, które wydaje się dodawać kilka dodatkowych kontroli lint. Jedną z tych kontroli lint jest dla jednorazowych wywołań RxJava2 subscribe(), które nie są przechowywane w zmiennej. Na przykład, uzyskanie listy wszystkich graczy z bazy mojego pokoju:

Single.just(db)
            .subscribeOn(Schedulers.io())
            .subscribe(db -> db.playerDao().getAll());

Powoduje duży żółty blok i ten tooltip:

Wynik subscribe nie jest używany

Tutaj wpisz opis obrazka

Jaka jest najlepsza praktyka dla połączeń One-shot Rx w ten sposób? Czy Powinienem Trzymać Disposable i dispose() na kompletnym? A może powinienem po prostu @SuppressLint i ruszyć dalej?

EDIT wydaje się, że dotyczy to tylko RxJava2 (io.reactivex), RxJava (rx) nie ma tego lint.

Author: Michael Dodd, 2018-03-28

4 answers

IDE nie wie, jakie potencjalne skutki może mieć Twoja subskrypcja, gdy nie zostanie usunięta, więc traktuje ją jako potencjalnie niebezpieczną. Na przykład, Single może zawierać wywołanie sieciowe, które może spowodować wyciek pamięci, jeśli {[2] } zostanie przerwana podczas jego wykonywania.

Wygodnym sposobem zarządzania dużą ilością Disposable S jest użycie CompositeDisposable; po prostu utwórz nową zmienną instancji CompositeDisposable w swojej klasie zamkniętej, a następnie dodaj wszystkie CompositeDisposable(z RxKotlin można po prostu dołączyć addTo(compositeDisposable) do wszystkich swoich jednorazowych). Na koniec, gdy skończysz z instancją, zadzwoń compositeDisposable.dispose().

To pozbędzie się ostrzeżeń lint i upewni się, że twoje Disposables są prawidłowo zarządzane.

W tym przypadku kod wyglądałby następująco:

CompositeDisposable compositeDisposable = new CompositeDisposable();

Disposable disposable = Single.just(db)
        .subscribeOn(Schedulers.io())
        .subscribe(db -> db.get(1)));

compositeDisposable.add(disposable); //IDE is satisfied that the Disposable is being managed. 
disposable.addTo(compositeDisposable); //Alternatively, use this RxKotlin extension function.


compositeDisposable.dispose(); //Placed wherever we'd like to dispose our Disposables (i.e. in onDestroy()).
 47
Author: urgentx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-08 21:59:46

W momencie, gdy aktywność zostanie zniszczona, lista przedmiotów jednorazowych zostanie wyczyszczona i jesteśmy gotowi.

io.reactivex.disposables.CompositeDisposable mDisposable;

    mDisposable = new CompositeDisposable();

    mDisposable.add(
            Single.just(db)
                    .subscribeOn(Schedulers.io())
                    .subscribe(db -> db.get(1)));

    mDisposable.dispose(); // dispose wherever is required
 13
Author: Aks4125,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-03 04:07:59

Jak sugerowano, możesz użyć jakiegoś globalnego CompositeDisposable, aby dodać tam wynik operacji subskrybowania.

Biblioteka rxjava2extensions zawiera przydatne metody do automatycznego usuwania utworzonych obiektów jednorazowego użytku z CompositeDisposable po jego zakończeniu. Zobacz sekcję SubscribeAutoRelease , ale zauważ, że jest błąd w nazwaniu metody subscribeAutoRelease zamiast subscribeAutoDispose.

W Twoim przypadku może to wyglądać tak

SingleConsumers.subscribeAutoDispose(
    Single.just(db)
            .subscribeOn(Schedulers.io()),
    composite,
    db -> db.playerDao().getAll())
 3
Author: httpdispatch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-03 07:03:47

Jeśli jesteś pewien, że disposable jest poprawnie obsługiwane, na przykład za pomocą operatora doOnSubscribe (), możesz dodać to do Gradle:

android {
lintOptions {
     disable 'CheckResult'
}}
 -1
Author: Ivan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-02 12:32:07