Как обновить вид после данных, полученных от подписки на наблюдаемую?
Я использую 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());
}
Это из-за CalledFromWrongThreadException
при выполнении this::displayCharacteristics
, Как правильно отобразить данные в потоке, в котором находится фрагмент? Должен ли я использовать слушателя? Спасибо!
2 ответа
Для взаимодействия с пользовательским интерфейсом в ОС Android вам необходимо находиться в главном потоке. Когда имеешь дело с 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())
поскольку выполнение будет быстро передано фоновому потоку.
Ваш код может выглядеть так, чтобы работать с пользовательским интерфейсом:
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);
}
Вы хотите обработать свои данные в потоке ввода-вывода и отправленные данные обратно в потоке пользовательского интерфейса.
Вы можете сделать это с помощью этих планировщиков.
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() везде и обрабатывать их в вашем подписчике (как вы уже сделали)