
In der Android-Community bin ich auf drei Arten von Entwicklern gestoßen, die auf RxRelay gestoßen sind:
- Diejenigen, die nicht verstehen, warum RxRelay in ihrem Projekt verwendet wird, warum es benötigt wird und wie es sich vom Thema unterscheidet
- Diejenigen, die denken, dass RxRelay Fehler "verschluckt" oder "nachdem der RxRelay-Fehler aufgetreten ist, wird es weiterhin funktionieren, aber das Subjekt wird nicht" (dieselbe Magie)
- Diejenigen, die wirklich wissen, was RxRelay ist.
Während die ersten beiden Typen häufiger vorkommen, habe ich beschlossen, einen Artikel zu schreiben, der Ihnen hilft, die Funktionsweise von RxRelay zu verstehen und seine "magischen" Eigenschaften zu überprüfen.
Wenn Sie RxJava verwenden, verwenden Sie wahrscheinlich Subject oder RxRelay, um Ereignisse von einer Entität in eine andere zu werfen oder aus imperativem Code reaktiven Code zu erstellen.
Schauen wir uns # 2 an und sehen, was der Unterschied zwischen RxRelay und Subject ist. Wir haben also zwei Abonnements für ein Relais. Wenn wir auf die Schaltfläche klicken, drücken wir eines auf dieses Relais.
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)
}
}
}
Wir klicken dreimal hintereinander auf die Schaltfläche und sehen ein solches Protokoll.
D / Test: Kette mit Fehler: onNext
D / Test: Kette ohne Fehler: onNext
D / Test: Kette mit Fehler: onError
D / Test: Kette ohne Fehler: onNext
D / Test: Kette ohne Fehler: onNext
Wenn Sie die Variable RxRelay durch ersetzen PublishSubject, das Protokoll wird nicht geändert. Hier ist der Grund:
Beim ersten Klick übertragen wir Daten in unser Relais. Beide Teilnehmer werden ausgelöst.
Beim zweiten Klick in der Kette erhält der erste Abonnent (disposable1) einen Fehler.
Beim dritten Klick wird der erste Einweg1 nicht mehr ausgelöst, da er den Terminalstatus onError erhalten hat. Dann funktioniert nur der zweite Einweg2.
Dies ist bei Subject und RxRelay der Fall. Ich möchte Sie daran erinnern, dass Fehler in rx die Kette entlang zum Teilnehmer (stromabwärts) gehen und über dem Ort, an dem sie aufgetreten sind, nicht auftreten. Am Ende haben wir überprüft, ob die RxRelay-basierte Verkettung nach dem Auftreten des Fehlers nicht funktioniert.
Wenn es also keinen Unterschied im Verhalten von Subject und RxRelay gibt, was ist dann ihr Unterschied?
Folgendes schreibt der Entwickler selbst in der README-Datei zu github:
"Grundsätzlich: Ein Betreff, außer ohne die Möglichkeit, onComplete oder onError aufzurufen."
Das heißt, es ist nur ein Betreff ohne die Methoden onComplete und onError, selbst der Quellcode der Klassen ist fast identisch. Wenn wir diese Methoden für den Betreff aufrufen, funktioniert er nicht mehr, da er einen Terminalstatus erhält. Daher hat der Autor der Bibliothek entschieden, dass es sich lohnt, diese Methoden zu entfernen, da Entwickler, die diese Subject-Eigenschaft nicht kennen, sie versehentlich aufrufen können.
Schlussfolgerung: Der einzige Unterschied zwischen RxRelay und Subject besteht darin, dass zwei Methoden onComplete und onError fehlen, sodass der Entwickler den Terminalstatus nicht aufrufen kann.