RxJava可观察对象之间的动态切换

时间:2019-03-14 09:16:22

标签: kotlin rx-java reactive-programming

我有两个观察对象:一个发出从蓝牙连接接收的ByteArray,另一个发出定期服务器请求的结果。

fun observeBluetooth():Observable<ByteArray>
fun observeServer():Observable<ByteArray>

蓝牙连接状态可用(布尔变量或可观察值)

我需要在考虑以下要求的情况下结合观察值:

  1. 如果已连接蓝牙,则必须发出从observeBluetooth()接收的数据(并且不能发出服务器请求)
  2. 如果未连接蓝牙,则从observeServer()接收的数据 必须发出
  3. 如果恢复了蓝牙连接,则必须再次发射从observeBluetooth()接收的数据

如何使用RxJava / Kotlin做到这一点?

2 个答案:

答案 0 :(得分:3)

如果您有一个可观察的isBtConnected,则可以切换它:

val isBtConnected: Observable<Boolean> = ...
isBtConnected.switchMap {
    if (it) observeBluetooth()
    else observeServer()
}

答案 1 :(得分:0)

听起来像您可以根据蓝牙状态进行过滤。如果它是共享的原子变量:

final AtomicBoolean isConnected = new AtomicBoolean();

Observable.merge(
    observeBluetooth()
       .filter(v -> isConnected.get()),
    observeServer()
       .filter(v -> !isConnected.get())
)
// ... etc.

如果状态也是可观察到的,则由于扩展项目中需要valve运算符而使状态变得更加复杂:

Observable<Boolean> isConnectedSource = ...

Observable<Boolean> shared = isConnectedSource.publish().refCount(2);

Observable.merge(
    observeBluetooth()
       .compose(ObservableTransformers.valve(shared)),
    observeServer()
       .compose(ObservableTransformers.valve(shared.map(v -> !v), false))
)
// ... etc.

请注意,valve将在关闭时暂停并继续缓冲项目。如果您需要从其他序列中删除项目,则必须结合两种方法:

Observable<Boolean> isConnectedSource = ...

final AtomicBoolean isConnected = new AtomicBoolean();

Disposable status = isConnectedSource.subscribe(v -> isConnected.set(v));

Observable.merge(
    observeBluetooth()
       .filter(v -> isConnected.get()),
    observeServer()
       .filter(v -> !isConnected.get())
)
// ... etc.

status.dispose();