在从暂停的存储库获取的 ViewModel 中传递 LiveData 的正确方法

Proper way to pass LiveData in ViewModel taken from suspended Repository

我正在全神贯注于 Kotlin 协程和 LiveData。我想做一个非常基本的用例,其中 ViewModel returns LiveData 从 Repository 暂停功能中获取,returns LiveData 也是如此。

存储库函数签名:

suspend fun getAll() : LiveData<List<Mountain>> 

它不能简单地这样做:

fun getMountains() : LiveData<List<Mountain>> {
  return mountainsRepository.getAll()
}

因为编译器声明应该从协程或另一个挂起函数调用挂起函数。 我提出了 2 个丑陋的解决方案,但我知道它们并不优雅:

1 runBlocking 解决方案

fun getMountains() : LiveData<List<Mountain>> = runBlocking { mountainsRepository.getAll() }

2 具有可空 LiveData 的解决方案

fun getMountains() : LiveData<List<Mountain>>?{
    var mountains : LiveData<List<Mountain>>? = null
    viewModelScope.launch{
        mountains = mountainsRepository.getAll()
    }
    return mountains
}

我怎样才能正确地做到这一点?

suspend fun getAll() : LiveData<List<Mountain>> 中删除 suspend 关键字

Room 中的 LiveData 已经是异步的,如果您使用 Room 获取实时数据,它将在后台正常工作。

Room, Coroutines, LiveData

它的体内有一个liveData builder可以调用挂起函数。 所以你的视图模型函数看起来像

fun getMountains() = liveData {
   emit(mountainsRepository.getAll()) 
}

确保您至少使用

implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"

正如 Lena 提到的那样 - 从您的存储库中删除 suspend getAll() 功能不会使其阻塞。

拥有

fun getAll() : LiveData<List<Mountain>> 

在你的回购中,

fun getMountains() = mountainsRepository.getAll()

在您的视图模型中,可能是实现相同目标的更好方法