Я перехожу с асинхронных задач на rxjava2, и у меня возникли проблемы с тестами кода.
У меня есть таблица элементов комнаты, у которых есть определенная денежная сумма. В пользовательском элементе управления, который называется DisplayCurrentBudget, должна отображаться сумма всех сумм. Это число должно обновляться каждый раз при вставке нового элемента. Я справился с этим требованием двумя способами, но оба дают один и тот же результат: мой код не заботится о том, обновляется ли база данных, он обновляется только при воссоздании фрагмента (onCreateView).
Моя первая попытка была такой:
//RxJava2 Test
Observable<ItemS> ItemObservable = Observable.create( emitter -> {
try {
List<ItemS> movies = oStandardModel.getItemsVanilla();
for (ItemS movie : movies) {
emitter.onNext(movie);
}
emitter.onComplete();
} catch (Exception e) {
emitter.onError(e);
}
});
DisposableObserver<ItemS> disposable = ItemObservable.
subscribeOn(Schedulers.io()).
observeOn(AndroidSchedulers.mainThread()).
subscribeWith(new DisposableObserver<ItemS>() {
public List<ItemS> BadFeelingAboutThis = new ArrayList<ItemS>();
@Override
public void onNext(ItemS movie) {
// Access your Movie object here
BadFeelingAboutThis.add(movie);
}
@Override
public void onError(Throwable e) {
// Show the user that an error has occurred
}
@Override
public void onComplete() {
// Show the user that the operation is complete
oBinding.DisplayCurrentBudget.setText(Manager.GetBigSum(BadFeelingAboutThis).toString());
}
});
Этот код меня уже не устраивал. Моя вторая попытка дает точно такой же результат:
Observable<BigDecimal> ItemObservable2 = Observable.create( emitter -> {
try {
BigDecimal mySum = oStandardModel.getWholeBudget();
emitter.onNext(mySum);
emitter.onComplete();
} catch (Exception e) {
emitter.onError(e);
}
});
DisposableObserver<BigDecimal> disposable = ItemObservable2.
subscribeOn(Schedulers.io()).
observeOn(AndroidSchedulers.mainThread()).
subscribeWith(new DisposableObserver<BigDecimal>() {
@Override
public void onNext(BigDecimal sum) {
// Access your Movie object here
oBinding.DisplayCurrentBudget.setText(sum.toString());
}
@Override
public void onError(Throwable e) {
// Show the user that an error has occurred
}
@Override
public void onComplete() {
// Show the user that the operation is complete
}
});
Есть ли очевидные проблемы с моим кодом?
Спасибо за чтение, очень признателен!
Редактировать: Меня спросили, что делает Manager.GetBigSum, на самом деле это не так много. Он только добавляет BigDecimal-Values в список элементов.
public static BigDecimal GetBigSum(List<ItemS> ListP){
List<BigDecimal> bigDList = ListP.stream().map(ItemS::get_dAmount).collect(Collectors.toList());
return bigDList.stream()
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
Далее я упростил запрос. Но он по-прежнему не заботится об обновлениях БД, а только о воссоздании фрагментов:
Single.fromCallable(() -> oStandardModel.getItemsVanilla())
.map(Manager::GetBigSum)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
e -> oBinding.DisplayCurrentBudget.setText(e.toString())
);
Я поставил GetBigSum в свой вопрос, большое вам спасибо.
В показанном коде нет ничего, что указывало бы на то, что последний элемент был удален. Возможно, у вас неправильный запрос к источнику данных или getItemsVanilla() не содержит данных, которые, по вашему мнению, должны.





В вашей логике rx нет ошибок. Это должна быть внутренняя ошибка вашего getWholeBudget.
Но почему вы пишете rx так сложно?
Для вашего случая вы можете просто написать:
Single.fromCallable(() -> oStandardModel.getItemsVanilla())
.map(Manager::GetBigSum)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
e -> oBinding.DisplayCurrentBudget.setText(sum.toString()),
e -> log.error(e));
Большое спасибо, я мог значительно упростить код (я указал текущее состояние в своем вопросе). Я выяснил, в чем суть проблемы - запрос выполняется при воссоздании формы, а не при изменении базы данных. Я думал, что суть наблюдаемых в том, чтобы реагировать на изменения БД?
Я решил это так:
oStandardModel.getItemJointCatLive().observe(this, new Observer<List<ItemJointCat>>() {
@Override
public void onChanged(@Nullable final List<ItemJointCat> oItemSP) {
Single.fromCallable(() -> oStandardModel.getWholeBudget())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
e -> oBinding.DisplayCurrentBudget.setText(e.toString())
);
}
});
Моя ошибка заключалась в том, что я предполагал, что RXjava2 не нуждается в событии onchanged ... теперь я просто использую событие onchanged наблюдателя Liveata для запуска простого запроса rxjava2.
Как вы думаете, есть ли что-то неправильное в таком подходе?
Не уверен, что вы имеете в виду. Индексы массива отсчитываются от нуля, поэтому
entry[0] to entry[length-1]имеет все записи массива. Как реализованGetBigSum?