【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]
\ アプリをリリースしました /
環境
- Android Studio:Narwhal Feature Drop
- Kotlin:2.1.10
- Material3
- AGP:8.9.2
- Gradle:8.11.1
- Mac M1:Sequoia 15.6.1
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 {
println("作成タイミングで実行される")
// 非同期で実行したい処理など
}.subscribeOn(Schedulers.io())
.subscribeBy(
onError = { error -> Log.e("RxJava", error.toString()) },
onComplete = { Log.i("RxJava", "完了" ) }
).addTo(compositeDisposable)
もちろんCompletableであることに変わりはないのでラムダ内で実行した処理の返り値などは取得できません。返り値を取得したい場合はSingle.fromCallbleメソッドで代用できます。
Completable.deferメソッド
Completable.fromActionは購読された時ではなく作成時点で処理が実行されます。これを購読タイミングで発火するようにしたい場合はCompletable.deferを使用します。
val completable = Completable.defer {
Completable.fromAction {
println("subscribe されたタイミングで実行される")
}
}
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:完了またはエラーを発行
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。






