0

我正在将 RxAndroidBle 用于一个项目,我需要从 ble 设备上读取一些特征,然后将它们显示在屏幕上。下面的代码工作除了this::displayCharacteristics

private void readCharacteristics() {
    mConnectionObservable.flatMap(rxBleConnection -> Observable.combineLatest(
            rxBleConnection.readCharacteristic(UUID_SERIAL_NUMBER),
            rxBleConnection.readCharacteristic(UUID_MACHINE_TYPE),
            rxBleConnection.readCharacteristic(UUID_CHARACTERISTIC),
            ConnectedViewModel::new
            ).doOnError(this::logError)
    ).doOnError(this::logError)
    .subscribe(this::displayCharacteristics, this::logError);
}


private void displayCharacteristics(ConnectedViewModel model) {
    mSerialNumber.setText(model.getSerialNumber());
    mMachineType.setText(model.getMachineType());
    mCableLength.setText(model.getCableLength());
    mCableSize.setText(model.getCableSize());
    mUnits.setText(model.getUnits());
}

这是因为CalledFromWrongThreadException执行this::displayCharacteristics. 在片段所在的线程上显示数据的正确方法是什么?我必须使用监听器吗?谢谢!

4

2 回答 2

2

您希望在 IO 线程中处理您的数据,并在 UI 线程中处理返回的数据。

您可以通过使用这些调度程序来做到这一点。

private void readCharacteristics() {
    mConnectionObservable.flatMap(rxBleConnection -> Observable.combineLatest(
            rxBleConnection.readCharacteristic(UUID_SERIAL_NUMBER),
            rxBleConnection.readCharacteristic(UUID_MACHINE_TYPE),
            rxBleConnection.readCharacteristic(UUID_CHARACTERISTIC),
            ConnectedViewModel::new
            ).doOnError(this::logError)
    ).doOnError(this::logError)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(this::displayCharacteristics, this::logError);
}

您还应该避免在任何地方使用所有这些 .doOnError() 并在您的订阅者中处理它(正如您已经完成的那样)

于 2017-09-20T20:55:08.477 回答
0

要在 Android 操作系统上与 UI 交互,您需要在主线程上。与您打交道时,RxJava您可以通过添加一行轻松地做到这一点.observeOn(AndroidSchedulers.mainThread())

截至版本1.4.0 RxAndroidBle 不再具有对RxAndroid库的传递依赖。要使用AndroidSchedulers类,您需要自己在build.gradle文件中添加一个依赖项:

dependencies {
    compile 'io.reactivex:rxandroid:1.2.1'
}

RxAndroidBle库自行处理 BLE 命令的线程化,因此几乎不需要使用.subscribeOn(Schedulers.io()),因为执行将很快移交给后台线程。

您的代码可能看起来像这样与 UI 一起使用:

private void readCharacteristics() {
    mConnectionObservable.flatMap(rxBleConnection -> Observable.combineLatest(
            rxBleConnection.readCharacteristic(UUID_SERIAL_NUMBER),
            rxBleConnection.readCharacteristic(UUID_MACHINE_TYPE),
            rxBleConnection.readCharacteristic(UUID_CHARACTERISTIC),
            ConnectedViewModel::new
        )
        .doOnError(this::logError)
    )
    .doOnError(this::logError)
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(this::displayCharacteristics, this::logError);
}
于 2017-09-21T10:37:36.307 回答