RxJava: AutoDisposeで自動的にdisposeする

非同期処理を開始した後に, Activityのライフサイクルなどに連動して非同期処理をキャンセルする必要があります.

RxJavaでは, Disposableからキャンセルの処理を行います.

Disposable d;

public void onCreate() {
    d = myObservable
        .map(a -> b)
        .subscribe();
}

public void onPause() {
    d.dispose();
}

このコードだと, ストリームの定義と, キャンセルのコードが離れ過ぎているため, 可読性が低いです.

AutoDisposeを使うことで, コード離れすぎ問題を解決することが出来ます.

public void onCreate() {
    myObservable
        .to(new ObservableScoper<>(this))
        .subscribe();
}

このような感じで, ストリームの定義の中にAutoDisposeが提供しているScoperを埋め込むことで自動的にdisposeしてくれます.

また, Scoperは, カスタムで柔軟に定義することが出来ます. 例えば,

など, こちら側で実装することが出来ます(実装の手間は少し掛かります)

これで, Disposableをマニュアルで呼び出すことから解放されます!

Error Proneと組み合わせると最強

とはいえ, そもそもScopeをストリームに埋め込むのを忘れる問題があります(だって人間だもの)

そこで, Googleが出したError Proneを組み合わせることで埋め込むのを忘れる問題を解決出来ます.

Error ProneはJavaの間違った使い方を教えてくれる Linterのようなものです. これを使うと,

public void onCreate() {
    myObservable
        .map(a -> b)
        .subscribe();
}

と, Scopeの指定を忘れた時に, エラーを出力してくれます. なぜかというと, RxJava2は @CheckReturnValueが返り値についているため, それをError Proneが検知してくれるためです.

public void onCreate() {
    myObservable
        .to(new ObservableScoper<>(this))
        .subscribe();
}

と書くと, @CheckReturnValueが返り値についていない Disposableが返されるようになるので, 返り値をチェックしなくてもError Proneに引っかかることはなくなります.

RxJavaのdispose忘れはついやってしまいがちですが, AutoDispose + Error Proneを組み合わせることで機械的に防ぐことが出来ます!

まとめ

Written by
あんどろいどでぃべろっぱぁー🍎