android - 使用协程在 Room 中的 ViewModel 中显示 LiveData
问题描述
这个问题是关于使用 MVVM、LiveData、Room(以及 RetroFit)和协同例程的 Android 编程的最佳实践。最佳实践之一指出
像网络或数据库调用这样的长时间运行的执行应该与 UI 线程异步执行。
当前的文档和博客详细解释了如何使用协同程序来执行此操作,并且一些示例很好地展示了这一点,例如向日葵应用程序。
我缺少的部分是当 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
- 有什么其他策略可以做到这一点?有什么例子吗?
- 这种策略对于网络请求会有所不同吗?
解决方案
房间执行数据库查询是异步的吗?如果是这样,它是否使用协同程序?
它正在执行异步,不,它不使用协程。LiveData 是生命周期感知的,因此只有在被恢复的 LifecycleOwner 观察到时才会调用它,例如 Fragment。
这是一个好习惯吗?因为repo只返回LiveData,只能用来返回LiveData
有点儿。如果您观看https://www.youtube.com/watch?v=zbYYoL7vo9Y和https://www.youtube.com/watch?v=B8ppnjGPAGE,您会发现他们正在远离在您的存储库中使用 LiveData或数据源,而是在这些层中使用协程。重要的是要了解您的调用属于哪个协程范围。Fi,当用户看不到结果时它应该完成吗?
有什么其他策略可以做到这一点?有什么例子吗?这种策略对于网络请求会有所不同吗?
Android 小镇的新热点是协同程序与 Flow 结合使用。如果你使用 Retrofit 进行网络调用,它现在也支持协程。一个不错的代码实验室是这个:https ://codelabs.developers.google.com/codelabs/kotlin-coroutines/#0
推荐阅读
- python - python中的Crypto-js AES加密
- c - 为什么我在 c 中反转字符串的函数不起作用?
- scala - 在将构造函数参数传递给 Scala 中的超类构造函数之前修改构造函数参数
- node.js - npm 错误!cb() 在创建第一个反应项目时从未在 windows10 上调用过
- python - numpy列表的元素降序排列
- swiftui - 选择器在表单中显示为禁用...错误?
- xamarin - 在将内存流转换为字节数组时,应用程序显示为黑屏并在 xamarin.forms 中终止
- excel - 复制活动行并在下面插入,即使使用活动过滤器
- r - 使用 lapply 的矩阵子集列表
- c++ - 从 std::cout 理解 operator<<()