Создание Jetpack с помощью RxJava2 и Realm

#android #realm #rx-java2 #android-jetpack-compose

#Android #realm #rx-java2 #android-jetpack-compose

Вопрос:

Я работаю над новым приложением для Android, используя Jetpack Compose (1.0.0-alpha08) и RxJava2 для управления потоком данных из моей модели (в данном случае области 10. Для данного экрана у меня есть модель представления, которая определяет данные, на которые будет подписано компостируемое представление верхнего уровня. Так, например:

ViewModel…

 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(...) {
     .......
   }
}
 

Все работает так, как я ожидал, и список отображается на экране так, как я хочу. Однако я предполагаю, что здесь произойдет то, что подписка произойдет только один раз, и поток будет выдавать новые данные только по мере того, как будут выдаваться новые данные. В результате я бы ожидал, что различные методы onNext будут запускаться только при наличии новых данных в потоке, например, что-то изменилось в realm db. Поскольку я не добавляю / не удаляю какие-либо данные в / из области, как только я получу первый набор результатов, я бы ожидал, что поток станет «тихим».

Однако, когда я выполняю вышеуказанное, сообщение subscribe, связанное с подпиской на realm, регистрируется снова и снова. То же самое для «Hello» и других операторов ведения журнала в методах onNext. Кроме того, если я добавлю какое-либо ведение журнала в свою функцию объединения, я вижу эти инструкции журнала так же, как я вижу журнал «Привет». Из этого кажется, что каждый раз, когда составляется список, он повторно подписывается на поток из моей viewmodel и запускает полный процесс. Как я уже сказал, я ожидал, что эта подписка произойдет только один раз.

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

Ответ №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())
 

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