如何在可观察的订阅中收到数据后更新视图?

时间:2017-09-20 20:47:16

标签: android observable rxandroidble

我正在使用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());
}

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

2 个答案:

答案 0 :(得分: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()并在您的订阅者中处理它(就像您已经完成的那样)

答案 1 :(得分:0)

要在Android OS上与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);
}