Я работаю над новым приложением для Android, используя Jetpack Compose (1.0.0-alpha08) и RxJava2 для управления потоком данных из моей модели (в данном случае Realm 10). Для данного экрана у меня есть модель представления, которая определяет данные, на которые будет подписано компостируемое представление верхнего уровня. Так, например:
ПросмотретьМодель...
class ListItemViewModel: ViewModel() {
val items: Flowable<Item>
get() {
val data1 = userRealm.where<Item1>()
.also(query).findAllAsync().asFlowable()
.onBackpressureLatest().doOnNext{System.out.println("Realm on Next")}
.observeOn(
Schedulers.single()
).filter{it.isLoaded}.map{ result ->
System.out.println("Maping Realm")
result
}.doOnSubscribe {System.out.println("Subscribe")}
val data2 == //same as above but with a different item
return Flowable.combineLatest(data1, data2, combineFunction)
.onBackpressureLatest()
.doOnNext{System.out.println("Hello")}
.doOnComplete {System.out.println("Complete")}
.subscribeOn(AndroidSchedulers.mainThread())
}
}
Вид
@Compostable
fun List(List<Item> items) {
val viewModel: ListItemViewModel = viewModel()
val list by viewModel.items.subscribeAsState(initial = listOf())
ItemList(list = list)
}
@Compostable
fun ItemList(List<Item> items {
LazyColumnFor(...) {
.......
}
}
Все работает так, как я ожидал, и список отображается на экране так, как я хочу. Однако я предполагаю, что здесь произойдет то, что подписка произойдет только один раз, и Flowable будет выдавать новые данные только по мере того, как новые данные будут испускаться. В результате я ожидаю, что различные методы onNext будут запускаться только тогда, когда в потоке будут присутствовать новые данные, например. что-то изменилось в сфере db. Поскольку я не добавляю/удаляю какие-либо данные в/из Realm, как только у меня будет первый набор результатов, я ожидаю, что поток станет «молчаливым».
Однако, когда я запускаю приведенное выше, сообщение о подписке, связанное с подпиской на область, регистрируется снова и снова. То же самое для «Hello» и других операторов ведения журнала в методах onNext. Кроме того, если я добавлю какое-либо ведение журнала в свою функцию объединения, я увижу эти операторы журнала так же, как я вижу журнал «Hello». Из этого кажется, что каждый раз, когда компонуемый список отображается, он повторно подписывается на Flowable из моей модели представления и запускает полный процесс. Как я уже сказал, я ожидал, что эта подписка произойдет только один раз.
Возможно, это правильное поведение, но мысленно мне кажется, что я сжигаю циклы ЦП без всякой причины, поскольку мои методы вызываются снова и снова, когда данные не меняются. Правильно ли я все настроил, или что-то не так в том, как я настроил?
В конечном итоге я решил проблему и применил гибридный подход, в котором я использовал Realm/RXJava для обработки потока данных и, когда что-то изменилось, обновлял объект LiveData.
Посмотреть модель
private val internalItemList = MutableLiveData(listOf<Item>())
val itemList: LiveData<List<Item>> = internalItemList
//capture the subscription so you can dispose in onCleared()
val subscription = items.observeOn(AndroidSchedulers.mainThread()).subscribe {
this.internalItemList.value = it
}
Вид
val list by viewModel.itemList.observeAsState(listOf())
Это должно быть менее болтливым и работает так, как я хочу. Не уверен, что это правильный способ сделать это, но, похоже, он работает