带有Kotlin-coroutines的房间观察数据库的变化

问题描述 投票:5回答:2

因此,我最近开始使用协同程序进行实验,我从Rxjava2切换到协同程序,我还没有掌握它但仍然,我遇到了一个需要观察我的数据库更改并更新对应的UI的情况。

RxJava曾经为我提供Flowables,Completeable等,使用它我可以观察到Db的变化。

    abstract fun insert(data: SomeData): Long

    @Query("SELECT * FROM somedata_table")
    abstract fun getData(): Flowable<List<SomeData>>

所以现在这里我曾经订阅了getData并且总是习惯于观察变化

现在输入coroutines,我使用带有延迟结果的暂停函数来返回我的响应

    @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。

android kotlin kotlinx.coroutines
2个回答
5
投票

原版的:

你应该使用LiveData替代RxJavaFlowableSingle等 - > LiveData)。在您使用RxJava(更新与房间DB更改相对应的UI)的背景下,LiveData将为您完成相同的工作,只是它由Google创建并专门设计为外部库的替代品。它是Architecture Components堆栈的一部分,与Room相同。

如需使用房间阅读herehere的指导。

当谈到将Coroutines与Room集成时,似乎目前有no out-of-the-box solution providedit is being worked on。你可能可以使用this article


更新:

从2.1室(Alpha)开始,添加了对Kotlin Coroutines的支持。有关如何使用它的一些细节可以在this article中找到。

注意:Room尚不支持频道,因为它仍然是一个实验性功能。


祝好运 :)


3
投票

Gradle依赖项:

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

© www.soinside.com 2019 - 2024. All rights reserved.