![](/img/trans.png)
[英]Android Room Kotlin - Query in background thread - return value problem
[英]Get a single object from a Room query in a background thread and use it in the view. Android/Kotlin/MVVM
在我目前的解决方案中,我使用协程并在 view.kt class 观察到的ViewModel
中返回一个MutableLiveData
。
道 function:
@Query(
"SELECT workout_name FROM workout_table " +
"WHERE id = :workoutId"
)
suspend fun getWorkoutName(workoutId: Long): String
存储库 function:
@WorkerThread
suspend fun getWorkoutName(workoutId: Long): String {
return database.workoutDao().getWorkoutName(workoutId)
}
查看模型 function:
fun getWorkoutName(workoutId: Long): MutableLiveData<String> {
val workoutName = MutableLiveData<String>()
CoroutineScope(Dispatchers.IO).launch {
workoutName.postValue(repository.getWorkoutName(workoutId))
}
return workoutName
}
查看.kt function:
private fun setUpAppBar() {
binding?.apply {
viewModel.getWorkoutName(currentWorkoutId!!).observe(viewLifecycleOwner) {
editWorkoutTopAppbar.title = it
}
}
}
这行得通,但我认为有更好的方法可以做到这一点。 我的主要问题出在ViewModel
中,因为我正在制作一个MutableLiveData
变量,将其返回到视图并在准备就绪时为其赋值。
我见过的另外两种方法是从 DAO 和存储库函数返回LiveData
并让视图观察它,但我认为这种方式不会在后台线程中完成数据库查询。 另一种方法是让 view.kt 文件启动协程,但我认为视图不应该启动协程。
存储库返回 LiveData 时使用协程的 ViewModel:
fun getWorkoutName(workoutId: Long): LiveData<String> {
CoroutineScope(Dispatchers.IO).launch {
return repository.getWorkoutName(workoutId)
}
}
上面的代码给我一个错误,因为我从协程内部返回结果。
请让我知道一个解决方案,或者如果我以错误的方式解决这个问题。
首先,最好使用viewModelScope
而不是创建新协程 scope,因为如果viewModelScope
被销毁,viewModelScope 会自行取消。 其次,您需要将 LiveData 公开给片段或活动而不是 MutableLiveData,因为无法从外部操作 LiveData。
所以你的 viewModel 应该看起来像这样:
private val _workoutName = MutableLiveData<String>()
val workoutName : LiveData<String>() get() = _workoutName
fun getWorkoutName(workoutId: Long) {
viewModelScope.launch {
_workoutName.postValue(repository.getWorkoutName(workoutId))
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.