在RxAndroidBle
的RxJava2版本中,函数readCharacteristic()
和writeCharacteristic()
返回Single<byte[]>
。
读取特征的示例代码是:
device.establishConnection(false).flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(characteristicUUID))
但是flatMap()
的文档说映射函数应该返回ObservableSource
。在这里,它返回Single
。这怎么办?
更新:我查看了使用.single()
和.singleOrError()
等运算符的可能性,但它们似乎都要求上游发出一个项目然后完成。但是establishConnection()
并没有完成。 (这是我建议将establishConnection()
重新设想为Maybe
的原因之一,并提供其他一些方式来断开连接,而不仅仅是取消订阅。)
答案 0 :(得分:2)
你完全正确,这个例子无法编译。它可能是RxJava1版本的遗留物,其中Single
不存在
具有相同结果的简单修复是使用RxJava2 flatMapSingle
例如:
device.establishConnection(false)
.flatMapSingle(rxBleConnection -> rxBleConnection.readCharacteristic(characteristicUUID))
flatMapSingle
接受Single
作为返回值,并将输入Single
的成功值映射到上游Observable
的发射。
关键是,RxJava具有更具体的Observable
类型,它们暴露了此Observable
期望的可能的一系列排放。现在有些方法返回Single
,因为这是它们的流(readCharacteristic()
)的逻辑运算,有些是Observable
,因为它们将发出多于单个发射(establishConnection()
- 连接状态可以随着时间的推移而改变。)
但是RxJava2还提供了许多运算符来在不同类型之间进行转换,这实际上取决于您的需求和场景。
答案 1 :(得分:0)
谢谢Rob!
事实上,README已被弃用,并且需要一些拉皮条。请看看它现在好不好。
答案 2 :(得分:0)
我想我找到了我想要的答案。关键点:
Single.fromObservable(observableSource)
在收到observableSource
的第二个项目之前不做任何事情!假设它收到的第一个项是有效的发射,那么如果第二个项是:
onComplete()
,它将第一项传递给onSuccess()
; onNext()
,它发出IndexOutOfBoundsException
信号,因为Single
不能发出多个项目; onError()
,它可能会将错误转发到下游。 现在,device.establishConnection()
是一项,未完成 Observable
。它发出的RxBleConnecton
是flatMapped到Single
readCharacteristic()
。但是(另一个问题),flatMapSingle
订阅这些Single
并将它们组合成Observable
,直到源establishConnection()
完成后才会完成。但来源并没有完成!因此,我们尝试创建的Single
不会发出任何内容,因为它没有收到必要的 second 项。
解决方案是强制在第一个(也是唯一的)项目之后生成onComplete()
,这可以使用take(1)
来完成。这将满足我们正在创建的Single
,并使其发出我们感兴趣的特征值。希望这很清楚。
代码:
Single<byte[]> readCharacteristicSingle( RxBleDevice device, UUID characteristicUUID ) {
return Single.fromObservable(
device.establishConnection( false )
.flatMapSingle( connection -> connection.readCharacteristic( characteristicUUID ) )
.take( 1L ) // make flatMapSingle's output Observable complete after the first emission
// (this makes the Single call onSuccess())
);
}