延迟初始化存储库

时间:2020-09-30 18:23:03

标签: android kotlin

我签出了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
        }
    }
}

}

在这里gardenPlantingRepositoryplantRepository可以访问房间数据库。 我不知道这行得通,因为通常无法在主线程上访问会议室数据库。 Viemodel用于PlantDetailFragment中并进行了延迟初始化。

@Inject
lateinit var plantDetailViewModelFactory: PlantDetailViewModel.AssistedFactory

private val plantDetailViewModel: PlantDetailViewModel by viewModels {
    PlantDetailViewModel.provideFactory(
        plantDetailViewModelFactory,
        args.plantId
    )
}

如果我尝试完全相同的操作,我总是会遇到无法访问主线程上的数据库的问题。因此,我尝试使用initcoroutineDispatchers.IO函数中初始化变量,但是这样做的问题是,当我访问视图模型的成员变量时,它们没有被初始化。那么向日葵应用程序的行为如何可重现

1 个答案:

答案 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