[Android] RxJavaを使ってn秒間に1回だけ処理を行う

Androidでn秒に1回だけ処理を行おうとすると、TimerやHandler、Runnableを使うことになると思いますが、なかなか面倒くさいです。RxJavaを使うと、n秒間に1回だけ処理を行う、という実装を少しだけ楽にできます。その実装方法をここに示しておきます。

ライブラリの導入

まずはライブラリを導入します。RxJava、RxAndroidを使います。エラーログの出力のために、お好みでTimberも導入しておきます。以下の記述をapp/build.gradleに追加したら、syncして準備は完了です。

dependencies {
    // RxAndroid
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'

    // RxJava
    implementation 'io.reactivex.rxjava2:rxjava:2.2.5'

    // Timber
    implementation 'com.jakewharton.timber:timber:4.7.1'
}

実装する

これで準備は整いました。RxJavaを用いて、n秒間に1回処理をするという実装を行います。以下のように実装します。

disposable = Observable.interval(1, TimeUnit.SECONDS)
    .subscribeOn(Schedulers.newThread())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe ({
        // do something here
    }, { throwable ->
        Timber.e(throwable)
    })
  • Observable#intervalを使って、定期的にObservableを発行します。インターバルを第1引数で、そのタイムユニットを第2引数で指定しています。今回は、1秒ごとに1個のObservableが発行されます。
  • Schedulers.newThread()を使って、バックグラウンドで実行しています。
  • AndroidSchedulers.mainThread()を使って、結果をフォアグラウンドで受け取っています。

ちなみに、Observable#takeを使うとObservableを発行する回数を指定することができます。

disposable = Observable.interval(1, TimeUnit.SECONDS)
    .take(60)
    .subscribeOn(Schedulers.newThread())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe ({
        // do something here
    }, { throwable ->
        Timber.e(throwable)
    })

以上でn秒間に1回だけ処理を行うという実装ができましたが、最後にdisposableをしかるべき場所で処理しておきましょう。

disposable?.dispose()
disposable = null