web-dev-qa-db-ja.com

購読の結果は使用されません

私は今日Android Studio 3.1にアップグレードしました。それはもう少し糸くずのチェックを追加したようです。これらのlintチェックの1つは、変数に格納されていないワンショットRxJava2 subscribe()呼び出しに対するものです。例えば、私のRoomデータベースから全プレイヤーのリストを取得する:

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

大きな黄色いブロックとこのツールチップが表示されます。

subscribeの結果は使用されていません

Screenshot of Android Studio. Code is highlighted in Yellow with a tooltip. Tooltip text: The result of subscribe is not used.

このようなワンショットRxコールのためのベストプラクティスは何ですか? Disposabledispose()を完全に把握する必要がありますか?それとも@SuppressLintだけで先に進みますか?

これはRxJava2(io.reactivex)にのみ影響するようですが、RxJava(rx)にはこのリントはありません。

90
Michael Dodd

IDEは、購読が破棄されない場合に購読にどのような影響を及ぼす可能性があるのか​​を認識していないため、安全ではないと見なされます。たとえば、Singleにネットワークコールが含まれていると、実行中にActivityが破棄されるとメモリリークが発生する可能性があります。

大量のDisposableを管理する便利な方法は、 CompositeDisposable を使用することです。囲んでいるクラスに新しいCompositeDisposableインスタンス変数を作成してから、すべてのDisposablesをCompositeDisposableに追加します(RxKotlinを使用すると、すべてのDisposablesにaddTo(compositeDisposable)を追加することができます)。最後に、インスタンスが完成したら、compositeDisposable.dispose()を呼び出します。

これは糸くずの警告を取り除き、あなたのDisposablesが適切に管理されるようにします。

この場合、コードは次のようになります。

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()).
84
urgentx

アクティビティが破棄される瞬間に、使い捨て用品のリストがクリアされ、私たちは良い状態になります。

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
25
Aks4125

提案されたように、あなたはそこに購読操作の結果を加えるために何らかのグローバルなCompositeDisposableを使うかもしれません。

RxJava2Extensions ライブラリには、完了時にCompositeDisposableから作成された使い捨てを自動的に削除するための便利なメソッドが含まれています。 subscribeAutoDispose sectionを参照してください。

あなたの場合それはこのように見えるかもしれません

SingleConsumers.subscribeAutoDispose(
    Single.just(db)
            .subscribeOn(Schedulers.io()),
    composite,
    db -> db.playerDao().getAll())
5
httpdispatch

DisposableSingleObserver でサブスクライブできます:

Single.just(db)
    .subscribeOn(Schedulers.io())
    .subscribe(new DisposableSingleObserver<Object>() {
            @Override
            public void onSuccess(Object obj) {
                // work with the resulting todos...
                dispose();
            }

            @Override
            public void onError(Throwable e) {
                // handle the error case...
                dispose();
            }});

Singleオブジェクトを直接破棄する必要がある場合(たとえば、放出する前に)Disposable参照を取得して使用するメソッドonSubscribe(Disposable d)を実装できます。

独自のSingleObserverインターフェースを実現するか、他の子クラスを使用することもできます。

2
papandreus