如何使用协程从 Room 返回单个(非 LiveData)对象

Flo*_*her 6 kotlin android-room android-livedata android-architecture-components kotlin-coroutines

LiveDataRoom 执行的查询会自动在后台线程上返回。但我想返回一个未包装的单个值LiveData(因为我不想要实时更新)。如何使用协程来实现这一点?

如何Task从该函数返回对象?

fun getTask(id: Int): Task {
    viewModelScope.launch {
        repository.getTask(id)
    }
}
Run Code Online (Sandbox Code Playgroud)

该函数位于 ViewModel 内部。它将调用转发给 DAO:

@Query("SELECT * FROM task_table WHERE id = :id")
fun getTask(id: Int): Task
Run Code Online (Sandbox Code Playgroud)

Ge3*_*3ng 3

如果您不从 Room 返回 LiveData,您将无法从数据库获取更新。但是,您可以从 viewModel 返回 LiveData。

val data = liveData {
    emit(repository.getTask(id))
}
Run Code Online (Sandbox Code Playgroud)

扩展liveData函数在协程中运行,然后您可以使用 DAO 的挂起版本来正确处理后台。

@Query("SELECT * FROM task_table WHERE id = :id")
suspend fun getTask(id: Int): Task?
Run Code Online (Sandbox Code Playgroud)

您需要做的一件大事是,如果您在查询中没有使用聚合函数,请确保它可以为空。

如果您确实想调用 viewModel 中的方法来返回任务,您应该从您的活动/片段运行启动(不推荐)

ViewModel
suspend fun getTask(id: Int): Task {
    repository.getTask(id)
}

Activity/Fragment
lifecycleScope.launch {
    val task = viewModel.getTask(id)
    // Do What you want with the task
}
Run Code Online (Sandbox Code Playgroud)