在RxJava中使用多个.subscribe()语句

时间:2017-06-19 18:51:01

标签: android bluetooth-lowenergy rx-java reactive-programming rxandroidble

我的BLE外设Android应用程序会写入2种不同的设备特征,并接收来自其他2个设备的通知。 RxAndroidBle库的开发人员警告同一个RxBleConnection实例上的多个订阅,但我没有看到任何将所有这些I / O操作合并为单个.subscribe()的现实方法,特别是因为其中一个通知是一个非常恒定的数据“firehose”。

不知道更好,我只是将RxBleConnection存储在变量中并在多个.subscribe()中使用它。据我所知,这一直很好。我已经调查了RxAndroidBle库的ConnectionSharingAdapter但是,虽然我已经分析了代码,但我不明白它提供了什么好处而不是我的简单方法(尽管我很想知道)。

一般来说,对多个.subscribe()引入状态的方式以及潜在的陷阱的一些阐述会有所帮助。问题:

  1. RxBleConnection存储在变量中并将其用于多个.subscribe() s有什么问题?
  2. 如果这是一个问题,ConnectionSharingAdapter如何解决?
  3. 说多个订阅“引入状态”是什么意思,这怎么会导致问题?
  4. 是否有任何干净的方法将所有四个特征I / O操作合并为一个.subscribe()(不会降低性能)?

1 个答案:

答案 0 :(得分:3)

  

RxBleConnection存储在变量中并将其用于多个.subscribe() s有什么问题?   (......)   说多个订阅"引入状态"是什么意思,以及这怎么会导致问题?

这两个问题几乎相同。 RxBleConnection是一种状态的抽象,其中BLE客户端与BLE服务器交换一些握手数据包,之后客户端和服务器都被认为是连接的。不幸的是,由于各种原因,这种连接几乎可以在任何时候被破解(并且经常发生),RxBleConnection的单个存储变量不能以反应的方式轻易表达。

另一方面,一旦连接中断,观察RxBleDevice.establishConnection()将向订户传播错误。虽然一旦连接断开,发出的RxBleConnection的功能都不起作用 - 连接的已保存变量在发生时不会通知问题。

因此,如果用户将RxBleConnection保存到变量中,则会引入变量可能处于的状态,并且用户负责传播(清除变量)稍后可能发生的错误。相反,订阅.establishConnection()将在无法使用连接时发出异常。

正如许多程序员在实践中可能已经注意到的那样 - 管理状态是应用程序中最常见的错误来源。减少状态是减少错误风险的一种方法。

杰克沃顿从Devoxx那里得到了很好的(但非常先进的)演讲:Managing State with RxJava by Jake Wharton

  

如果这是一个问题,ConnectionSharingAdapter如何解决?

由于BLE连接和通信的状态特性(请求 - 响应是众所周知的模式)并且具有多个.establishConnection(),因此.subscribe() observable不允许同时具有多个子记录。使用相同连接可能会导致对另一个的干扰而代码中没有明确的跟踪。这就是为什么BleAlreadyConnectedException为不遵循使用RxBleConnection的代码中所有位置的用户引入的原因。 ConnectionSharingAdapter作为帮助者被引入,用户有意识地决定在多个交互器之间共享单个连接。如果RxBleConnection被破坏,ConnectionSharingAdapter会将错误传播到所有Subscriber

  

是否有任何干净的方法将所有四个特征I / O操作合并为一个.subscribe()(不会降低性能)?

在大多数情况下,可以干净地组合许多I / O.上面提到的谈话涉及这个话题。正确组合多个I / O需要额外分配的成本,但由于此通信通道的速度较慢,因此在处理BLE时很少出现问题。