私は今日Android Studio 3.1にアップグレードしました。それはもう少し糸くずのチェックを追加したようです。これらのlintチェックの1つは、変数に格納されていないワンショットRxJava2 subscribe()
呼び出しに対するものです。例えば、私のRoomデータベースから全プレイヤーのリストを取得する:
Single.just(db)
.subscribeOn(Schedulers.io())
.subscribe(db -> db.playerDao().getAll());
大きな黄色いブロックとこのツールチップが表示されます。
subscribe
の結果は使用されていません
このようなワンショットRxコールのためのベストプラクティスは何ですか? Disposable
とdispose()
を完全に把握する必要がありますか?それとも@SuppressLint
だけで先に進みますか?
これはRxJava2(io.reactivex
)にのみ影響するようですが、RxJava(rx
)にはこのリントはありません。
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()).
アクティビティが破棄される瞬間に、使い捨て用品のリストがクリアされ、私たちは良い状態になります。
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
提案されたように、あなたはそこに購読操作の結果を加えるために何らかのグローバルなCompositeDisposable
を使うかもしれません。
RxJava2Extensions ライブラリには、完了時にCompositeDisposable
から作成された使い捨てを自動的に削除するための便利なメソッドが含まれています。 subscribeAutoDispose sectionを参照してください。
あなたの場合それはこのように見えるかもしれません
SingleConsumers.subscribeAutoDispose(
Single.just(db)
.subscribeOn(Schedulers.io()),
composite,
db -> db.playerDao().getAll())
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
インターフェースを実現するか、他の子クラスを使用することもできます。