【Kotlin/Android】RxJavaのCompletableの使い方!完了の是非だけ通知
この記事からわかること
- Android Studio/KotlinでRxJavaの使い方
- Completableクラスの生成方法
- Observableオブジェクトとの違い
- fromActionメソッドの使い方
- io.reactivex.rxjava3.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with.エラーの原因
- Single/Maybeとの違い
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
環境
- Android Studio:Flamingo
- Kotlin:1.8.20
Completableとは?
RxJavaのCompletable
クラスは非同期処理が完了したかどうかだけを通知できるObservableオブジェクトの1種です。APIリクエストが成功したかだけを知りたい場合や画像の保存処理などただ結果を通知させたい場合などに利用することが可能です。
実装方法はObservableクラスと同じようにcreate
メソッドを使用してCompletable
オブジェクトを生成し、emitter
からonError
またはonComplete
メソッドを使用することで各イベントを発火させることができます。
Completable.create { emitter ->
if (true) {
emitter.onError(Exception("ERROR"))
} else {
emitter.onComplete()
}
}.subscribeBy(
onError = { error -> Log.e("RxJava",error.toString()) },
onComplete = { Log.i("RxJava", "完了" ) }
).addTo(compositeDisposable)
インスタンス生成メソッド
create
メソッドだけでなく単に完了イベントまたはエラーイベントをのみを発行するCompletable
オブジェクトを生成するためのcomplete
メソッドとerror(Throwable)
メソッドも用意されています。
// 完了のみ
Completable.complete().subscribeBy(
onComplete = { Log.i("RxJava", "完了" ) }
).addTo(compositeDisposable)
// エラーのみ
Completable.error(Exception("ERROR")).subscribeBy(
onError = { error -> Log.e("RxJava",error.toString()) }
).addTo(compositeDisposable)
fromActionメソッド
Completable.fromAction
は引数に渡した処理を非同期的に実行し正常に完了したかどうかだけを取得したい場合に活用できるメソッドです。fromAction
に渡したラムダ式内の処理が全て完了すればonComplete
が発火され、何かしらのエラーが発生すればonError
が発火され、subscribeBy
などから結果を取得することができるようになります。
Completable.fromAction {
// 非同期で実行したい処理など
}.subscribeOn(Schedulers.io())
.subscribeBy(
onError = { error -> Log.e("RxJava", error.toString()) },
onComplete = { Log.i("RxJava", "完了" ) }
).addTo(compositeDisposable)
もちろんCompletable
であることに変わりはないのでラムダ内で実行した処理の返り値などは取得できません。返り値を取得したい場合はSingle.fromCallble
メソッドで代用できます。
io.reactivex.rxjava3.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with.
使用する際に使い方を間違えると以下のようなエラーが発生することがあります。
io.reactivex.rxjava3.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with.
これは例えば以下のようにonError
とonComplete
が同時に発火してしまうような実装になっている場合に発生します。
Completable.create { emitter ->
emitter.onComplete()
if (true) {
emitter.onError(Exception("ERROR") )
}
}.subscribeBy(
onError = { error -> Log.e("RxJava",error.toString()) },
onComplete = { Log.i("RxJava", "完了" ) }
).addTo(compositeDisposable)
Completableを直列に繋げる
複数の非同期処理を実行する場合に「非同期処理Aが完了してから非同期処理Bを実行する」といった直列に処理を繋げたい場合はandThen
メソッドを使用します。使用方法は以下の記事を参考にしてください。
Single/Maybe/Completableの違い
Completable
クラスと似たようなイベント発行するクラスにSingle
とMaybe
があります。それぞれの違いは以下の通りです。
- Single:データを1回、またはエラーを発行
- Maybe:データを1回もしくはデータなしで完了のみまたはエラーを発行
- Completable:完了またはエラーを発行
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。