Jetpack компонуется с RxJava2 и Realm

Я работаю над новым приложением для 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 из моей модели представления и запускает полный процесс. Как я уже сказал, я ожидал, что эта подписка произойдет только один раз.

Возможно, это правильное поведение, но мысленно мне кажется, что я сжигаю циклы ЦП без всякой причины, поскольку мои методы вызываются снова и снова, когда данные не меняются. Правильно ли я все настроил, или что-то не так в том, как я настроил?

2
0
2 970
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В конечном итоге я решил проблему и применил гибридный подход, в котором я использовал 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())

Это должно быть менее болтливым и работает так, как я хочу. Не уверен, что это правильный способ сделать это, но, похоже, он работает

Другие вопросы по теме