android - 在 Android 上的视图模型中使用 Dagger 2 单例
问题描述
我希望我的应用程序具有以下架构:
-di // dependancy injection package
-model
--datasources // implementations of repositories, using dao to return data
--dao // access to the database (room)
--repositories // interfaces
-ui // activities, fragments...
-viewmodels // viewmodels of each fragment / activity which will return data to the views in the ui package
在 Android 上,人们似乎通常在活动中进行依赖注入,但我想在视图模型中注入我的存储库。
我有一个使用手动创建的 LiveData 的特定视图模型
class NavigationViewModel(application: Application) : AndroidViewModel(application) {
init {
DaggerAppComponent.builder()
.appModule(AppModule(getApplication()))
.roomModule(RoomModule(getApplication()))
.build()
.injectNavigationViewModel(this)
}
@Inject
lateinit var displayScreenRepository: DisplayScreenRepository
fun setScreenToDisplay(screen: DisplayScreen) {
displayScreenRepository.setScreenToDisplay(screen)
}
}
在我的 RoomModule 中,我有这个提供者:
@Singleton
@Provides
internal fun displayScreenRepository(): DisplayScreenRepository {
return DisplayScreenDataSource()
}
DisplayScreenDataSource 类非常简单:
class DisplayScreenDataSource : DisplayScreenRepository {
private val screenToDisplay = MutableLiveData<DisplayScreen>()
override fun getScreenToDisplay(): LiveData<DisplayScreen> {
return screenToDisplay
}
override fun setScreenToDisplay(screen: DisplayScreen) {
if (Looper.myLooper() == Looper.getMainLooper()) {
screenToDisplay.value = screen
} else {
screenToDisplay.postValue(screen)
}
}
}
我希望这个单例可用于其他视图模型 MainActivityViewModel,所以我这样做了:
class MainActivityViewModel(application: Application) : AndroidViewModel(application) {
@Inject
lateinit var displayScreenRepository: DisplayScreenRepository
init {
DaggerAppComponent.builder()
.appModule(AppModule(application))
.roomModule(RoomModule(application))
.build()
.injectMainViewModel(this)
}
}
但是当我运行我的应用程序时,实例化的存储库没有相同的引用,并且当我在我的一个 ViewModel 中更新一个 LiveData 的值时,如果我观察到另一个 ViewModel 的 LiveData,它不是同一个 LiveData 所以是没有更新。
我的猜测是我没有正确实例化 DaggerAppComponent :它应该只创建一次并最终注入几次。那正确吗?
我应该在哪里存储 DaggerAppComponent 的实例?在应用程序类中?
我可以有这样的东西:
class MainActivityViewModel(application: Application) : AndroidViewModel(application) {
@Inject
lateinit var displayScreenRepository: DisplayScreenRepository
init {
(application as MyApplication).daggerAppComponent.injectMainViewModel(this)
}
}
这是推荐的方式吗?
解决方案
推荐阅读
- python - 在所有列中创建具有特定值计数的新列(例如,类似于 COUNTIF)?
- virtual-keyboard - 在 ansi 风格的键盘中,上面输入的反斜杠的 vk 代码是什么
- c++ - 是否可以使用 Google Mock 模拟“pthread_mutex_lock”?
- javascript - 为什么 momentjs 以错误的方式转换时区?
- javascript - 无法将变量传递给 Paypal Smart Button api 的值
- java - 查询以获取按列的不同属性排序的所有对象?
- javascript - 如何设置链接父级
- 在 React 中活跃?
- r - R:特定时间段内的平均变量
- macos - K8s:如何使用服务访问我的应用程序?
- vba - 如何使用 Word VBA 将内容控制复选框插入到 Outlook 任务中?