如何在从 observable 上的订阅接收到数据后更新视图?
How to update view after data received from subscribe on an observable?
我正在为一个项目使用 RxAndroidBle,我需要从蓝牙设备读取一些特性,然后将它们显示在屏幕上。以下代码适用于 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());
}
这是因为执行this::displayCharacteristics
时出现了CalledFromWrongThreadException
。在片段所在的线程上显示数据的正确方法是什么?我必须使用监听器吗?谢谢!
您想在 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() 并在您的订阅者中处理它(正如您已经完成的那样)
要与 Android OS 上的 UI 交互,您需要在主线程上。在处理 RxJava
时,您可以通过添加一行 .observeOn(AndroidSchedulers.mainThread())
.
轻松做到这一点
从版本 1.4.0
开始,RxAndroidBle
不再对 RxAndroid
库具有传递依赖性。要使用 AndroidSchedulers
class 你需要自己在 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);
}
我正在为一个项目使用 RxAndroidBle,我需要从蓝牙设备读取一些特性,然后将它们显示在屏幕上。以下代码适用于 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());
}
这是因为执行this::displayCharacteristics
时出现了CalledFromWrongThreadException
。在片段所在的线程上显示数据的正确方法是什么?我必须使用监听器吗?谢谢!
您想在 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() 并在您的订阅者中处理它(正如您已经完成的那样)
要与 Android OS 上的 UI 交互,您需要在主线程上。在处理 RxJava
时,您可以通过添加一行 .observeOn(AndroidSchedulers.mainThread())
.
从版本 1.4.0
开始,RxAndroidBle
不再对 RxAndroid
库具有传递依赖性。要使用 AndroidSchedulers
class 你需要自己在 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);
}