当前,我正在尝试重构my source code以使用RxAndroidBle库。
我实现了一个状态机,该状态机在每次蓝牙成功操作(通知,写入,读取等)下调用下一个状态。只要蓝牙设备正在运行,就应该始终建立rxBleConnection。
我的设置通知实现如下:
Foos
如果我只在通知中设置了该特性,那么它起作用了,但是如果发生错误或尝试再次设置它,我将陷入doOnNext的无限循环中,并且setNotificationOn方法永远不会终止。我认为doOnNext在成功的通知设置中仅被调用一次! (永远不会引发BleConflictingNotificationAlreadySetException或其他异常!?)
如何重复设置相同特征的通知?
是否有更好的方法用RxAndroidBle / RxJava2创建状态机? (我需要依次调用各种蓝牙操作)
您会发现我的完整实现here
编辑:
但是,如果有人尝试再次订阅.setupNotification() 对于相同的特征,两个订户将共享相同的 通知。
感谢您的解释,因此不会再次调用protected void setNotificationOn(UUID characteristic) {
if (isConnected()) {
final Disposable disposable = connectionObservable
.flatMap(rxBleConnection -> rxBleConnection.setupNotification(characteristic))
.doOnNext(notificationObservable -> {
Timber.d("Successful set notification on for %s", BluetoothGattUuid.prettyPrint(characteristic));
nextMachineStateStep();
}
)
.flatMap(notificationObservable -> notificationObservable)
.observeOn(AndroidSchedulers.mainThread())
.retry(BT_RETRY_TIMES_ON_ERROR)
.subscribe(
bytes -> {
onBluetoothNotify(characteristic, bytes);
Timber.d("onCharacteristicChanged %s: %s",
BluetoothGattUuid.prettyPrint(characteristic),
byteInHex(bytes));
},
throwable -> onError(throwable)
);
compositeDisposable.add(disposable);
}
}
,因为如果我再次订阅doOnNext()
,则通知已成功设置。
是否可以检查通知是否已设置(以便我可以跳过此步骤以转到我的下一个计算机状态)?
您的API为什么看起来像这样或您到底想要实现什么
我想实现通过RxAndroidBle的蓝牙通信是抽象的,以便setupNotification()
的子类可以使用以下方法:
class BluetoothCommunication
设置蓝牙通信顺序。蓝牙通信/序列/算法始终是不同的,并且无法设置参数。但这总是顺序的。要初始化蓝牙规模,首先需要先设置A,然后再设置B。其次,我必须先发送命令C,然后再发送命令B,这样我将收到一个或多个通知呼叫,依此类推。我支持来自不同供应商的许多蓝牙秤,命令/设置通知和算法的数量总是不同的。
您可以看到带有各种算法here的子类
以我的经验,RxJava2不需要具有其他状态 机器,因为它已经是一个处理状态的库
如何抽象子类的库句柄状态?
答案 0 :(得分:0)
我认为doOnNext仅在成功设置通知后被调用一次!?
在您的情况下,建立连接后,每次成功设置通知都会调用此.doOnNext()
。如果连接由于任何原因而中断,.retry()
操作员将重新订阅connectionObservable
,这可能会启动新的连接,从而触发新的通知设置。
结论:每个.doOnNext()
的{{1}}可能被调用BT_RETRY_TIMES_ON_ERROR
次
如何重复设置相同特征的通知?
只要订阅了.subscribe()
,通知就处于活动状态,而无需重新设置。但是,如果一个用户尝试再次订阅.setupNotification()
以获得相同的特征,则两个订阅者将共享相同的通知。在您的示例中,通知将一直有效,直到.setupNotification()
被处置或连接断开(在这种情况下,如上所述,每个订阅最多可以建立compositeDisposable
次新连接)。 / p>
是否有更好的方法用RxAndroidBle / RxJava2创建状态机? (我需要依次调用各种蓝牙操作)
RxJava2允许以许多不同的方式(也包括顺序的)构建状态转换并安排订阅特定的BT_RETRY_TIMES_ON_ERROR
,例如
Observable
还有其他一些运算符也可以使进程按顺序进行。
一个更合适的问题是,为什么您的API看起来像这样,或者您究竟想要实现什么,例如
Disposable disposable = Observable.concat(Arrays.asList(
Observable.just("start").doOnSubscribe(disposable1 -> Log.d("Subscribe", "start")),
Observable.just("0").delay(3, TimeUnit.SECONDS).doOnSubscribe(disposable1 -> Log.d("Subscribe", "0")),
Observable.just("1").delay(2, TimeUnit.SECONDS).doOnSubscribe(disposable1 -> Log.d("Subscribe", "1")),
Observable.just("2").delay(1, TimeUnit.SECONDS).doOnSubscribe(disposable1 -> Log.d("Subscribe", "2")),
Observable.just("end").doOnSubscribe(disposable1 -> Log.d("Subscribe", "end"))
))
.subscribe(s -> Log.d("Result", s));
// 2019-01-04 12:45:13.364 31887-31887/ D/Subscribe: start
// 2019-01-04 12:45:13.364 31887-31887/ D/Result: start
// 2019-01-04 12:45:13.364 31887-31887/ D/Subscribe: 0
// 2019-01-04 12:45:16.366 31887-32529/ D/Result: 0
// 2019-01-04 12:45:16.367 31887-32529/ D/Subscribe: 1
// 2019-01-04 12:45:18.367 31887-32535/ D/Result: 1
// 2019-01-04 12:45:18.368 31887-32535/ D/Subscribe: 2
// 2019-01-04 12:45:19.369 31887-32537/ D/Result: 2
// 2019-01-04 12:45:19.371 31887-32537/ D/Subscribe: end
// 2019-01-04 12:45:19.372 31887-32537/ D/Result: end
这样的单一方法)?根据我的经验,RxJava2不需要具有其他状态机,因为它已经是处理状态的库。一旦了解了需求,就可以按照完全满足需求的方式对RxJava2操作员链进行建模。
是否可以检查通知是否已设置(以便我可以跳过此步骤以转到我的下一个计算机状态)?
否,无法检查它-呼叫者知道它是否已经设置。