我签出了Android Sunflower最佳做法应用。而且,我有点难以理解PlantDetailsViewModel的初始化为何起作用。 该类的定义如下
class PlantDetailViewModel @AssistedInject constructor(
plantRepository: PlantRepository,
private val gardenPlantingRepository: GardenPlantingRepository,
@Assisted private val plantId: String
) : ViewModel() {
val isPlanted = gardenPlantingRepository.isPlanted(plantId)
val plant = plantRepository.getPlant(plantId)
....
@AssistedInject.Factory
interface AssistedFactory {
fun create(plantId: String): PlantDetailViewModel
}
companion object {
fun provideFactory(
assistedFactory: AssistedFactory,
plantId: String
): ViewModelProvider.Factory = object : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return assistedFactory.create(plantId) as T
}
}
}
}
在这里gardenPlantingRepository
和plantRepository
可以访问房间数据库。
我不知道这行得通,因为通常无法在主线程上访问会议室数据库。 Viemodel用于PlantDetailFragment中并进行了延迟初始化。
@Inject
lateinit var plantDetailViewModelFactory: PlantDetailViewModel.AssistedFactory
private val plantDetailViewModel: PlantDetailViewModel by viewModels {
PlantDetailViewModel.provideFactory(
plantDetailViewModelFactory,
args.plantId
)
}
如果我尝试完全相同的操作,我总是会遇到无法访问主线程上的数据库的问题。因此,我尝试使用init
和coroutine
在Dispatchers.IO
函数中初始化变量,但是这样做的问题是,当我访问视图模型的成员变量时,它们没有被初始化。那么向日葵应用程序的行为如何可重现
答案 0 :(得分:2)
存储库使用返回LiveData的Dao方法
Room持久性库支持可观察的查询,这些查询返回LiveData对象。可观察到的查询是作为数据库访问对象(DAO)的一部分编写的。
更新数据库时,Room会生成所有必需的代码来更新LiveData对象。必要时,生成的代码在后台线程上异步运行查询。此模式对于使UI中显示的数据与数据库中存储的数据保持同步非常有用。 https://developer.android.com/topic/libraries/architecture/livedata#use_livedata_with_room
如果要使用协程,则应在LiveData
中创建ViewModel
并将其公开
class ViewModel(
val repository: Repository
) : ViewModel() {
private val _liveData = MutableLiveData<SomeType>()
val liveData: LiveData<SomeType> get() = _liveData
init {
viewModelScope.launch(Dispatchers.IO) {
_liveData.postValue(repository.getSomeData())
}
}
}
然后您应该在活动/片段中观察此liveData