Androidコミュニティでは、RxRelayに出くわした3種類の開発者に出くわしました。
- プロジェクトでRxRelayが使用されている理由、必要な理由、Subjectとの違いを理解していない人
- RxRelayがエラーを「飲み込む」または「RxRelayエラーが発生した後は機能し続けるが、サブジェクトは機能しない」と考える人(同じ魔法)
- RxRelayが何であるかを本当に知っている人。
最初の2つのタイプがより一般的ですが、RxRelayがどのように機能するかを理解し、その「魔法の」プロパティを確認するのに役立つ記事を書くことにしました。
RxJavaを使用している場合は、SubjectまたはRxRelayを使用して、あるエンティティから別のエンティティにイベントをスローするか、必須コードからリアクティブコードを作成します。
ポイント2を確認して、RxRelayとSubjectの違いを確認しましょう。したがって、1つのリレーに2つのサブスクリプションがあり、ボタンをクリックすると、このリレーに1つプッシュします。
class MainActivity : AppCompatActivity() {
private val relay = PublishRelay.create<Int>()
private var isError: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val disposable1 = relay
.map {
if (isError) {
isError = false
throw Exception()
} else {
isError = true
}
}.subscribe(
{
Log.d("test", " : onNext")
},
{
Log.d("test", " : onError")
}
)
val disposable2 = relay
.subscribe(
{
Log.d("test", " : onNext")
},
{
Log.d("test", " : onError")
}
)
btn.setOnClickListener {
relay.accept(1)
}
}
}
ボタンを3回続けてクリックすると、そのようなログが表示されます。
D /テスト:エラーのあるチェーン:onNext
D /テスト:エラーのないチェーン:onNext
D /テスト:エラーのあるチェーン:onError
D /テスト:エラーのないチェーン:onNext
D /テスト:エラーのないチェーン:
onNextRxRelay変数を次のように置き換える場合PublishSubject、ログは変更されません。
その理由は次のとおりです。最初のクリックで、データをリレーにプッシュします。両方のサブスクライバーがトリガーされます。
チェーンの2回目のクリックで、最初のサブスクライバー(disposable1)にエラーが発生します。
3回目のクリックで、最初のdisposable1は終了状態onErrorを受け取ったため、起動しなくなりました。次に、2番目のdisposable2のみが機能します。
これは、SubjectとRxRelayの場合に当てはまります。 rxエラーでは、チェーンを下ってサブスクライバー(ダウンストリーム)に移動し、エラーが発生した場所より上では発生しないことを思い出してください。エラーが発生した後、RxRelayベースのチェーンが機能しないことを確認することになりました。
では、SubjectとRxRelayの動作に違いがない場合、それらの違いは何ですか?
開発者自身がGithubのREADMEに書いているものは次のとおりです。
「基本的に:onCompleteまたはonErrorを呼び出す機能がない場合を除いてサブジェクト。」
つまり、onCompleteメソッドとonErrorメソッドのない単なるサブジェクトであり、クラスのソースコードでさえほとんど同じです。サブジェクトでこれらのメソッドを呼び出すと、ターミナル状態を受け取るため、動作を停止します。したがって、ライブラリの作成者は、このSubjectプロパティについて知らない開発者が誤ってメソッドを呼び出す可能性があるため、これらのメソッドを削除する価値があると判断しました。
結論:RxRelayとSubjectの唯一の違いは、onCompleteとonErrorの2つのメソッドがないため、開発者は端末の状態を呼び出すことができないことです。