简体   繁体   English

从后台线程中的 Room 查询中获取单个 object 并在视图中使用它。 安卓/科特林/MVVM

[英]Get a single object from a Room query in a background thread and use it in the view. Android/Kotlin/MVVM

In my current solution to this I use coroutines and return a MutableLiveData in the ViewModel that the view.kt class observes.在我目前的解决方案中,我使用协程并在 view.kt class 观察到的ViewModel中返回一个MutableLiveData

DAO function:道 function:

@Query(
    "SELECT workout_name FROM workout_table " +
        "WHERE id = :workoutId"
)
suspend fun getWorkoutName(workoutId: Long): String

Repository function:存储库 function:

@WorkerThread
suspend fun getWorkoutName(workoutId: Long): String {
    return database.workoutDao().getWorkoutName(workoutId)
}

ViewModel function:查看模型 function:

fun getWorkoutName(workoutId: Long): MutableLiveData<String> {
    val workoutName = MutableLiveData<String>()
    CoroutineScope(Dispatchers.IO).launch {
        workoutName.postValue(repository.getWorkoutName(workoutId))
    }
    return workoutName
}

View.kt function:查看.kt function:

private fun setUpAppBar() {
    binding?.apply {
        viewModel.getWorkoutName(currentWorkoutId!!).observe(viewLifecycleOwner) {
            editWorkoutTopAppbar.title = it
        }
    }
}

This works but I think there's a better way of doing this.这行得通,但我认为有更好的方法可以做到这一点。 My main problem is in the ViewModel because I'm making a MutableLiveData variable, returning it to the view and giving it a value when ready.我的主要问题出在ViewModel中,因为我正在制作一个MutableLiveData变量,将其返回到视图并在准备就绪时为其赋值。

Two other ways I've seen is returning LiveData from the DAO and repository functions and having the view observe it, but this way I think the database query is not done in a background thread.我见过的另外两种方法是从 DAO 和存储库函数返回LiveData并让视图观察它,但我认为这种方式不会在后台线程中完成数据库查询。 Another way is having the view.kt file launch the coroutine but I believe the view is not supposed to launch coroutines.另一种方法是让 view.kt 文件启动协程,但我认为视图不应该启动协程。

The ViewModel using a coroutine when repository returns LiveData:存储库返回 LiveData 时使用协程的 ViewModel:

fun getWorkoutName(workoutId: Long): LiveData<String> {
    CoroutineScope(Dispatchers.IO).launch {
        return repository.getWorkoutName(workoutId)
    }
}

The above code gives me an error because I'm returning the result from inside a coroutine.上面的代码给我一个错误,因为我从协程内部返回结果。

Please let me know a solution, or maybe if I'm approaching this problem the wrong way.请让我知道一个解决方案,或者如果我以错误的方式解决这个问题。

First, it's better to use viewModelScope instead of creating new coroutines scope since viewModelScope cancels itself if the veiwModel gets destroyed.首先,最好使用viewModelScope而不是创建新协程 scope,因为如果viewModelScope被销毁,viewModelScope 会自行取消。 secondly, you need to expose a LiveData to fragment or activity instead of MutableLiveData because LiveData can not be manipulated from outside.其次,您需要将 LiveData 公开给片段或活动而不是 MutableLiveData,因为无法从外部操作 LiveData。

so your viewModel should look something like this:所以你的 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.

相关问题 Android Room Kotlin - 在后台线程中查询 - 返回值问题 - Android Room Kotlin - Query in background thread - return value problem 如何从 object 中的 hashmap 中获取值 kotlin ZC31B32364CE19CA8FCD150A417ECVCE58 - How to get values from an object in a hashmap in kotlin android using mvvm 从后台线程查询房间数据库 - Room Database Query from background Thread Android - 使用 Room 从 SQLite 获取单个 object - Android - Get a single object from SQLite using Room Android 开发中的协同程序是否仅适用于 Kotlin? 使用 MVVM 从 android 房间检索,如何让 id 立即返回活动? - Are Co-Routines in Android Development only for Kotlin? Retrieval from android room using MVVM, way to get id returned to activity immediately? 我是否必须使用 LiveData 从 Android - Kotlin 中的房间数据库中读取查询 - Do I have to use LiveData to read Query from Room DataBase in Android - Kotlin 房间中的查询构造(Android Kotlin) - Query construct in room (Android Kotlin) Android MVVM ROOM 单一事实来源问题 - Android MVVM ROOM Single Sources of Truth Question 在视图中获取标签号。 安卓系统 - Get the tab number in the View. Android Android Room SQLITE 使用 MVVM 更新自定义查询 - Android Room SQLITE Update Custom Query with MVVM
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM