【Kotlin/Android】RxJavaのBehaviorSubjectの使い方!PublishSubjectとの違い

この記事からわかること
- Android Studio/KotlinでRxJavaの使い方
- BehaviorSubjectオブジェクトとは?
- PublishSubjectとの違い
index
[open]
\ アプリをリリースしました /
環境
- Android Studio:Flamingo
- Kotlin:1.8.20
Subjectとは?
SubjectとはRxJavaにおけるイベントの検知と発生が可能なクラスです。RxJavaにおいてイベントの検知が可能なクラスといえばObservable
クラスですがさらに自身でイベント流せるのが大きな違いです。
流せるイベントはonNext
、onError
、onCompleted
の3つです。
さらにSubjectの中には「Publish」と「Behavior」に分かれそれぞれのクラスが定義されてます。両者の違いはバッファ(※)を持つか持たないかです。バッファを持つBehaviorは過去のイベントを受け取ることができるようになります。※バッファとはデータを一時的に記憶する場所を指すような言葉です。
クラス名 | 流せるイベント | バッファ |
---|---|---|
PublishSubject | onNext、onError、onCompleted | 無 |
BehaviorSubject | onNext、onError、onCompleted | 有 |
バッファという難しい書き方をしましたが要は値を自身で保持しているかしていないかです。BehaviorSubject
の場合はvalue
プロパティから保持している値を参照することができます。
RxSwift
ですがRelayとの違いを知りたい方は以下の記事を参考にしてください。
PublishSubjectの使い方
PublishSubject
オブジェクトはcreate
メソッドで生成します。その際に扱うデータ型を指定します。イベントを流したい場合はonNext
、onError
、onCompleted
メソッドを使用し、subscribe
で観測することで値が変化した時などに処理を実装することができます。
val publishSubject = PublishSubject.create<Int>()
publishSubject.subscribe { value -> println("Received value: $value") }
publishSubject.onNext(1) // 出力: "Received value: 1"
publishSubject.onNext(2) // 出力: "Received value: 2"
BehaviorSubjectの使い方
BehaviorSubject
オブジェクトはcreateDefault
メソッドで生成します。その際に初期値となる値を指定します。イベントを流したい場合はonNext
、onError
、onCompleted
メソッドを使用し、subscribe
で観測することで値が変化した時などに処理を実装することができます。
val behaviorSubject = BehaviorSubject.createDefault(0)
behaviorSubject.subscribe { value -> println("Current value: $value") }
behaviorSubject.onNext(1) // 出力: "Current value: 1"
behaviorSubject.onNext(2) // 出力: "Current value: 2"
PublishSubject
と異なり流れた最後の値を保持しているのでvalue
プロパティからその値を参照することができます。取得できるのはnull
の可能性もあるのでlet
などを使用して安全に参照します。
behaviorSubject.value?.let { value ->
println("Current value: $value")
}
Observableに変換する
BehaviorSubject
オブジェクトをObservable
に変換するにはhide
メソッドを使用します。これを使用することでクラス内部では変更可能なBehaviorSubject
として、外部には観測のみのObservable
として活用することができるようになります。
private val _counter = BehaviorSubject.createDefault<Int>(0)
val counter: Observable<Int> = _counter.hide()
nullを初期値に渡すクラッシュする
BehaviorSubject#createDefault
メソッドの定義を見てみると@NonNull
が付与されているため初期期にnull
を渡すと例外がスローされアプリがクラッシュしてしまいます。
@CheckReturnValue
@NonNull
public static <T> BehaviorSubject<T> createDefault(T defaultValue) {
return new BehaviorSubject<T>(defaultValue);
}
構文エラーにはならないので注意してください。
// ×
private val _counter = BehaviorSubject.createDefault<Int?>(null)
// ○
private val _counter = BehaviorSubject.createDefault<Int>(0)
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。