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

この記事からわかること

  • Android Studio/KotlinRxJava使い方
  • BehaviorSubjectオブジェクトとは?
  • PublishSubjectとの違い

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

Subjectとは?

SubjectとはRxJavaにおけるイベントの検知と発生が可能なクラスです。RxJavaにおいてイベントの検知が可能なクラスといえばObservableクラスですがさらに自身でイベント流せるのが大きな違いです。

流せるイベントはonNextonErroronCompletedの3つです。

さらにSubjectの中には「Publish」と「Behavior」に分かれそれぞれのクラスが定義されてます。両者の違いはバッファ(※)を持つか持たないかです。バッファを持つBehaviorは過去のイベントを受け取ることができるようになります。※バッファとはデータを一時的に記憶する場所を指すような言葉です。

クラス名 流せるイベント バッファ
PublishSubject onNext、onError、onCompleted
BehaviorSubject onNext、onError、onCompleted

バッファという難しい書き方をしましたが要は値を自身で保持しているかしていないかです。BehaviorSubjectの場合はvalueプロパティから保持している値を参照することができます。

RxSwiftですがRelayとの違いを知りたい方は以下の記事を参考にしてください。

PublishSubjectの使い方

PublishSubjectオブジェクトはcreateメソッドで生成します。その際に扱うデータ型を指定します。イベントを流したい場合はonNextonErroronCompletedメソッドを使用し、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メソッドで生成します。その際に初期値となる値を指定します。イベントを流したい場合はonNextonErroronCompletedメソッドを使用し、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")
}

公式リファレンス:BehaviorSubject

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)

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index