这个问题是关于使用MVVM,LiveData,Room(因此也包括RetroFit)和协同例程的Android编程最佳实践。最佳实践之一指出:
Long running executions such as Network - or Database calls should be performed asynchronous from the UI thread.
当前的文档和博客解释了如何使用协同例程详细执行此操作,一些示例很好地演示了此操作,例如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)
因此,没有范围,工作或任何与例程相关的东西。
我的问题:
最佳答案
Is room performing the DB query asynchronous? And if so, is it using co-routines?
它执行异步操作,不,它不使用协程。 LiveData具有生命周期感知功能,因此仅当恢复的LifecycleOwner(如Fragment)观察到它时才调用它。
Is this a good practice? Because the repo is only returning LiveData and can only be used to return LiveData
有点儿。如果您观看https://www.youtube.com/watch?v=zbYYoL7vo9Y和https://www.youtube.com/watch?v=B8ppnjGPAGE,您会发现它们正在避免在 repo 或数据源中使用LiveData,而是在这些层中使用协程。重要的是要了解您的调用属于哪个协程范围。 F.i.,如果用户看不到结果,是否应该完成?
What are other strategies to do this? Any examples? Would this strategy differ for network requests?
Android城镇中的新热点是将协同程序与Flow结合使用。如果您将Retrofit用于网络调用,则现在也支持协同程序。一个不错的代码实验室可以检查一下:https://codelabs.developers.google.com/codelabs/kotlin-coroutines/#0
关于android - 使用协程从Room在ViewModel中显示LiveData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58817055/