与协同程序所以,我最近开始实验,我从Rxjava2切换到协同程序,我还没有得到它的把握尚未但尽管如此,我遇到了,我需要观察我的数据库的变化和更新相应UI的条件
RxJava过去曾向我提供Flowable,Completeable等,使我能够观察Db的变化。
abstract fun insert(data: SomeData): Long
@Query("SELECT * FROM somedata_table")
abstract fun getData(): Flowable<List<SomeData>>
所以现在我在这里订阅了getData,并且总是用来观察更改
现在输入协程,我正在使用具有延迟结果的暂停函数返回我的回复
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract fun insert(data: SomeData): Long
@Query("SELECT * FROM somedata_table")
abstract fun getData(): List<SomeData>
suspend fun getAllSomeData():Deferred<List<SomeData>>{
return GlobalScope.async (context= coroutineContext){
database.myDao().getData()
}
}
现在我无法收听更新,协程中的频道可能是正确的答案?但我不确定如何在Room中使用它。
答案 0 :(得分:5)
原始:
您应使用undefined method `replace' for #<Nokogiri::XML::NodeSet:0x00007f4e458bbb78>
代替LiveData
(RxJava
,Flowable
等-> Single
)。在您使用LiveData
(正在更新与Room DB更改相对应的UI)的情况下,RxJava
将为您完成相同的工作,只是它由 Google 创建并专为替代外部库而设计。它是建筑组件堆栈的一部分,与 Room 相同。
有关如何在 Room 中使用它的指导,请阅读here和here。
在将协同程序与 Room 集成时,目前似乎有no out-of-the-box solution provided和it is being worked on。您可能可以使用this article。
更新:
自房间到 2.1(Alpha)起,添加了对科特林 协程的支持。在this article中可以找到有关如何使用它的一些详细信息。
注意: Room尚不支持频道,因为它仍然是实验功能。
祝你好运:)
答案 1 :(得分:5)
目前,有两种不同的方法可以做到这一点。第一种是使用liveData构建器函数。要使此工作有效,您需要将生命周期更新为androidx.lifecycle:*:2.2.0-alpha01
或任何更新的版本。 LiveData构建器函数将用于异步调用getData(),然后使用emit()发出结果。使用此方法,您可以将Room getData()函数修改为暂停函数,并使返回类型包装为LiveData,从而替换之前使用的Flowable。
@Query("SELECT * FROM somedata_table")
abstract suspend fun getData(): LiveData<List<SomeData>>
在视图模型中,创建一个引用Room数据库的liveData
val someData: LiveData<SomeData> = liveData {
val data = database.myDao().getData()
emit(data)
}
第二种方法是从数据库中获取数据作为Flow。要使用此功能,您需要将Room更新为androidx.room:room-*:2.2.0-alpha02
(当前为最新版本)或更高版本。此更新使@Query DAO方法的返回类型为Flow如果查询中的观察表无效,则返回的Flow将重新发射一组新值。声明具有Channel返回类型的DAO函数是错误的,Room鼓励您使用Flow,然后使用相邻的函数将Flow转换为Channel。
@Query("SELECT * FROM somedata_table")
abstract suspend fun getData(): Flow<List<SomeData>>
要获取和更新数据,我们将在Presenter / ViewModel中将接收到的冷数据流转换为热通道。最好在Android体系结构组件的ViewModel中执行此操作。下面给出的解决方案假定我们在具有提供的viewModelScope的ViewModel中进行此操作。
fun loadData(){
val channel = database.myDao().getData().distinctUntilChanged().produceIn(viewModelScope)
viewModelScope.launch {
for(i in channel){
withContext(Dispatchers.Main){ /** Update your obsevable data type with i **/ }
}
}
}
答案 2 :(得分:3)
使用 Room 2.2.0流程和 kotlin协程。它有争议,但我不喜欢 LiveData ,因为它可以在UI线程上为您提供结果。如果必须执行任何数据解析,则必须将所有内容推回另一个IO线程。与直接使用频道相比,它更干净,因为每次您想收听事件时,您都必须执行额外的 openSubscription()。consumeEach {..} 呼叫。
流方法需要以下版本:
//此版本在其非实验版本中使用协程和流程
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2
androidx.room:room-runtime:2.2.0
androidx.room:room-compiler:2.2.0
道:
@Dao
interface MyDao {
@Query("SELECT * FROM somedata_table")
fun getData(): Flow<List<SomeData>>
}
课堂观察:
launch {
dao.getData().collect { data ->
//handle data here
}
}
如果您的调用类本身不是 CoroutineScope ,则必须在上下文上下文中调用launch。可以是 GlobalScope 或您创建的其他一些类。
GlobalScope.launch {
dao.getData().collect { data ->
//handle data here
}
}
收集 lambda会像在Rx onNext 调用中一样,接收到表中的每个udpate。
答案 3 :(得分:2)
等级依赖性:
dependencies {
compile group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-reactive', version: '1.1.1'
}
房间
@Dao
interface HistoryDao : BaseDao<HistoryEntity> {
@Query("select * from History order by time desc")
fun observe(): Flowable<List<HistoryEntity>>
...
}
Interactor(下面的 browserHistoryInteractor )(位于dao和Fragment / Presenter之间的层)
// To get channel of List<HistoryEntity>:
import kotlinx.coroutines.reactive.openSubscription
fun observe() = historyDao.observe().openSubscription() // convert list to Coroutines channel
演示者/片段/活动(终点(在我的情况下,这是生命周期感知的演示者))
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
private val compositeJob = Job() // somewhat equivalent "compositeDisposable" in rx
override fun onCreate() {
super.onCreate()
launch(compositeJob) { // start coroutine
val channel = browserHistoryInteractor.observe()
for (items in channel) { // waits for next list of items (suspended)
showInView { view?.setItems(items) }
}
}
}
override fun onDestroy() {
compositeJob.cancel() // as in rx you need to cancel all jobs
super.onDestroy()
}
https://www.youtube.com/watch?v=lh2Vqt4DpHU&list=PLdb5m83JnoaBqMWF-qqhZY_01SNEhG5Qs&index=5在29:25