【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)
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。






