Jetpack 与 RxJava2 和 Realm 组合
Jetpack compose with RxJava2 and Realm
我正在开发一个新的 android 应用程序,它使用 Jetpack Compose (1.0.0-alpha08) 和 RxJava2 来管理来自我的模型(在本例中为 Realm 10)的数据流。对于给定的屏幕,我有一个视图模型,它定义了顶级 Compostable 视图将订阅的数据。因此,例如:
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(...) {
.......
}
}
一切如我所愿,列表按我的意愿呈现在屏幕上。但是,我假设这里会发生的是订阅只会发生一次,并且 Flowable 只会在发出新数据时推出新数据。因此,我只希望在流中出现新数据时触发各种 onNext 方法,例如领域数据库发生了一些变化。因为我不是 adding/deleting 任何数据 to/from 领域,所以一旦我有了第一组结果,我希望 flowable 会“沉默”。
但是,当我 运行 上面的内容时,与领域订阅相关的订阅消息被一遍又一遍地记录下来。 onNext 方法中的“Hello”和其他日志语句也是如此。此外,如果我在组合函数中添加任何日志记录,我会以与“Hello”日志相同的方式查看这些日志语句。由此看来,每次渲染 List 可组合项时,它都会从我的视图模型重新订阅 Flowable 并触发整个过程。正如我所说,我原以为这种订阅只会发生一次。
这也许是正确的行为,但在精神上,感觉我无缘无故地燃烧 CPU 个循环,因为当没有数据发生变化时我的方法被一遍又一遍地调用。我的设置是否正确,或者我的配置方式是否存在缺陷?
我最终解决了这个问题,并采用了一种混合方法,我使用 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())
这一定不那么啰嗦,而且可以按我想要的方式工作。不确定这样做是否正确,但它似乎有效
我正在开发一个新的 android 应用程序,它使用 Jetpack Compose (1.0.0-alpha08) 和 RxJava2 来管理来自我的模型(在本例中为 Realm 10)的数据流。对于给定的屏幕,我有一个视图模型,它定义了顶级 Compostable 视图将订阅的数据。因此,例如:
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(...) {
.......
}
}
一切如我所愿,列表按我的意愿呈现在屏幕上。但是,我假设这里会发生的是订阅只会发生一次,并且 Flowable 只会在发出新数据时推出新数据。因此,我只希望在流中出现新数据时触发各种 onNext 方法,例如领域数据库发生了一些变化。因为我不是 adding/deleting 任何数据 to/from 领域,所以一旦我有了第一组结果,我希望 flowable 会“沉默”。
但是,当我 运行 上面的内容时,与领域订阅相关的订阅消息被一遍又一遍地记录下来。 onNext 方法中的“Hello”和其他日志语句也是如此。此外,如果我在组合函数中添加任何日志记录,我会以与“Hello”日志相同的方式查看这些日志语句。由此看来,每次渲染 List 可组合项时,它都会从我的视图模型重新订阅 Flowable 并触发整个过程。正如我所说,我原以为这种订阅只会发生一次。
这也许是正确的行为,但在精神上,感觉我无缘无故地燃烧 CPU 个循环,因为当没有数据发生变化时我的方法被一遍又一遍地调用。我的设置是否正确,或者我的配置方式是否存在缺陷?
我最终解决了这个问题,并采用了一种混合方法,我使用 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())
这一定不那么啰嗦,而且可以按我想要的方式工作。不确定这样做是否正确,但它似乎有效