简体   繁体   English

使用存储库进行延迟初始化

[英]Lazy initialization with repository

I checked out the Android Sunflower best practices app.我查看了Android Sunflower最佳实践应用程序。 And i kinda struggle to understand why the initialization of the PlantDetailsViewModel is working.我有点难以理解为什么PlantDetailsViewModel的初始化有效。 The class is defined as follows该类定义如下

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
        }
    }
}

} }

here the gardenPlantingRepository and plantRepository give access to a Room Database .在这里, gardenPlantingRepositoryplantRepository可以访问Room Database I wonder that this works because normally it is not possible to access a room database on the main thread.我想知道这是否有效,因为通常无法访问主线程上的房间数据库。 The Viemodel is used in the PlantDetailFragment and lazy initialized. Viemodel 用于PlantDetailFragment并进行延迟初始化。

@Inject
lateinit var plantDetailViewModelFactory: PlantDetailViewModel.AssistedFactory

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

if i try something that is quite the same i always get the problem that it is not possible to access the database on the main thread.如果我尝试一些完全相同的东西,我总是会遇到无法访问主线程上的数据库的问题。 so i tried to init my variables in the init function with a coroutine and Dispatchers.IO but the problem with this is that when i access member variables of my viewmodel they are not initialized.所以我试图用coroutineDispatchers.IOinit函数中初始化我的变量,但问题是当我访问我的视图模型的成员变量时,它们没有被初始化。 so how is the behaviour of the sunflower app reproducible那么向日葵应用程序的行为如何重现

Repository uses Dao methods that return LiveData Repository 使用返回 LiveData 的 Dao 方法

The Room persistence library supports observable queries, which return LiveData objects. Room 持久性库支持可观察查询,它返回 LiveData 对象。 Observable queries are written as part of a Database Access Object (DAO).可观察查询是作为数据库访问对象 (DAO) 的一部分编写的。

Room generates all the necessary code to update the LiveData object when a database is updated.当数据库更新时,Room 会生成所有必要的代码来更新 LiveData 对象。 The generated code runs the query asynchronously on a background thread when needed.生成的代码在需要时在后台线程上异步运行查询。 This pattern is useful for keeping the data displayed in a UI in sync with the data stored in a database.此模式可用于使 UI 中显示的数据与存储在数据库中的数据保持同步。 https://developer.android.com/topic/libraries/architecture/livedata#use_livedata_with_room https://developer.android.com/topic/libraries/architecture/livedata#use_livedata_with_room

If you want to use coroutines then you should create and expose LiveData in your ViewModel如果你想使用协程,那么你应该在你的ViewModel创建和公开LiveData

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())
        }
    }

}

Then you should observe this liveData in your activity / fragment然后你应该在你的活动/片段中观察这个 liveData

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM