如何正确使用来自 Room 数据库的 get 查询的结果

How to properly use the result from a get query from a Room database

在我的应用程序中,我有一个锻炼列表,有一次我想使用 Room 数据库中的 ID 来获取一项锻炼的名称。为此,我在 DAO class 中进行了 SQL 查询,以使用其 ID 获取锻炼名称。我的主要问题是如何将它从 ViewModel 获取到视图。该应用程序使用协程。

DAO 函数:

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

存储库功能:

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

ViewModel 函数:

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

查看函数(片段.kt内class):

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

假设 'editWorkoutTopAppbar' 是一个 textView。

此代码有效,但请注意 ViewModel 和视图。在 ViewModel 我 return 一个 MutableLiveData 变量并在视图中观察它,我这样做是为了在值准备好时使用变量。 我意识到我可以在应用程序的开头获取所有锻炼并过滤它们以获得特定的锻炼,但我的目标是查询数据库。

ViewModel 获取此值的更简洁或更有效的方法是什么?

在我使用 LiveData 和 ViewModel 的项目中,我使用了 DataBinding。我将 ViewModel 设置为 xml 中的变量,并将 ViewModel 的变量绑定到视图:

<layout>

    
    <data>

        <variable
            name="viewModel"
            type="path.ViewModel" />
    </data>

    <TextView
        android:text="@{viewModel.variableName}" />

</layout>

片段:

val binding = DataBindingUtil.inflate(inflater, layoutRes, container, false)
binding.setVariable(BR.viewModel, viewModel)

可能的代码改进:

你也可以直接从你的 Dao return a LiveData:

道:

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

回购:

fun getWorkoutName(workoutId: Long): LiveData<String> = 
  database.workoutDao().getWorkoutName(workoutId)

视图模型:

// would always return only a LiveData instead of MutableLiveData so only the ViewModel can manipulate its value
fun getWorkoutName(workoutId: Long): LiveData<String> =
        workoutName.postValue(repository.getWorkoutName(workoutId))

关于协程:

ViewModel 中,您还可以将 viewModelScope 用于协程。