我正在创建一个简单的应用程序,用于使用RxAndroidBle库与蓝牙设备进行连接(干得好!)。
我遇到的问题有时是当我连接到设备时,收到状态为133的Gatt错误。
我知道它可能会发生,所以我想做的就是在发生该错误时重试所有内容。
没问题,我可以使用retryWhen()
运算符轻松地做到这一点,但是我还有另一个要求-流必须在之后终止
如果连接不成功,则等待30秒。我为此使用了timeout()
,但问题是当我重试时,计时器再次启动。
因此,问题是如何将timeout()运算符与retryWhen()结合使用,以便我可以重试某些特定错误,但保持计数器继续运行。
我对合并可观察变量有一些想法,或者有一些单独的可观察变量,它们将在超时时间段后检查连接状态,但是我
想知道我是否可以在单个可观察的范围内做到这一点。
到目前为止,我的代码如下所示:
public Observable<ConnectingViewState> connectToDevice(String macAddress) {
final RxBleDevice rxBleDevice = rxBleClient.getBleDevice(macAddress);
return rxBleDevice.establishConnection(false)
.subscribeOn(Schedulers.io())
.map(rxBleConnection -> new ConnectingViewState.ConnectedViewState(rxBleConnection))
.cast(ConnectingViewState.class)
.timeout(40, TimeUnit.SECONDS)
.startWith(new ConnectingViewState.ConnectingInProgressViewState())
.retryWhen(errors -> errors.flatMap(error -> {
if (isDefaultGattError(error)) {
return Observable.just(new Object());
} else {
return Observable.error(error);
}
}
))
.onErrorReturn(throwable -> new ConnectingViewState.ErrorState(throwable));
}
最佳答案
retryWhen
运算符通过重新订阅其上方的运算符链来工作。由于您将timeout
放在其前面,因此该超时被重新预订,因此从头开始重新计数。
将timeout
放在retryWhen
之后应将全局超时应用于整个可重试流。