【问题标题】:Displaying LiveData in ViewModel from Room with co-routines使用协程在 Room 中的 ViewModel 中显示 LiveData
【发布时间】:2020-03-08 01:36:28
【问题描述】:

这个问题是关于在 Android 编程中使用 MVVM、LiveData、Room(因此也包括 RetroFit)和协程的最佳实践。最佳实践之一指出

网络或数据库调用等长时间运行的执行应与 UI 线程异步执行。

当前的文档和博客详细解释了如何使用协同例程执行此操作,并且一些示例很好地证明了这一点,例如Sunflower App

我缺少的部分是当 ViewModel 被初始化并且它需要显示来自数据库/存储库/网络的内容时,如何使用协同程序进行加载。在Sunflower App 中,存储库正在返回 LiveData,但没有使用协程。

例子:

PlantDao 我们看到:

@Query("SELECT * FROM plants WHERE id = :plantId")
fun getPlant(plantId: String): LiveData<Plant>

因此没有suspend 关键字,这不是协同程序的一部分。

plantRepository 中有:

fun getPlant(plantId: String) = plantDao.getPlant(plantId)

再次没有suspend关键字所以没有协程。

PlantDetailViewModel中初始化向我们展示了

val plant = plantRepository.getPlant(plantId)

所以没有范围、工作或任何与协同程序相关的东西。

我的问题:

  • 房间执行数据库查询是异步的吗?如果是,是否使用协同程序?
  • 这是一个好习惯吗?因为repo只返回LiveData,只能用来返回LiveData
  • 还有哪些其他策略可以做到这一点?有什么例子吗?
  • 此策略对于网络请求会有所不同吗?

【问题讨论】:

    标签: android mvvm android-room android-livedata kotlin-coroutines


    【解决方案1】:

    房间执行数据库查询是异步的吗?如果是,是否使用协程?

    它正在执行异步,不,它不使用协程。 LiveData 是生命周期感知的,因此只有在被恢复的 LifecycleOwner 观察到时才会调用它,例如 Fragment。

    这是一个好习惯吗?因为repo只返回LiveData,只能用来返回LiveData

    有点。如果您观看 https://www.youtube.com/watch?v=zbYYoL7vo9Yhttps://www.youtube.com/watch?v=B8ppnjGPAGE,您会发现他们正在远离在您的存储库或数据源中使用 LiveData,而是在这些层中使用协程。重要的是要了解您的调用属于哪个协程范围。 F.i.,当用户看不到结果时它应该完成吗?

    还有哪些其他策略可以做到这一点?有什么例子吗?这种策略对于网络请求会有所不同吗?

    Android 小镇的新热点是结合 Flow 使用协程。如果你使用 Retrofit 进行网络调用,它现在也支持协程。一个不错的代码实验室是这个:https://codelabs.developers.google.com/codelabs/kotlin-coroutines/#0

    【讨论】:

    • 感谢您的回答!关于 Room with coroutines 和 LiveData 的文档应该更加明确,以便开发人员了解幕后发生的事情。
    猜你喜欢
    • 2021-04-01
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    相关资源
    最近更新 更多