![](/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.