gpt4 book ai didi

android - 使用 Dagger 跨两个/或多个 fragment 和一个 Activity 共享 ViewModel

转载 作者:行者123 更新时间:2023-12-04 02:41:05 24 4
gpt4 key购买 nike

好吧,正如我试图在标题中总结的那样,这是细节。

我们有一个相对较大的应用程序,它使用 Dagger,但方式并不理想,所以我们决定开始编写测试,为此,我需要公开 Mockito 的依赖项,因此,我遇到了一个问题,开始使用单例工厂,仍然适用,并且有大量的教程可以解释这一点。

我们的应用程序有很多功能,使用单个 Activity 和导航组件实现,单个 Activity 有时有一个创建的 View 模型,我们使用它在容器 Activity 和使用导航填充的 fragment 之间共享数据编辑。

我想不通的是,如何使用 dagger 注入(inject)共享 View 模型,每次调用 @Inject 时返回相同的实例对于特定的 View 模型,我知道它可以通过范围来完成,但我无法弄清楚,我有一个需要验证的解释。 (我将在下面提供我的代码)

我首先实现了我的 Singleton ViewModelFactory,如下所示:

@Singleton
class ViewModelFactory @Inject constructor(private val creators: Map<Class<out ViewModel>,
@JvmSuppressWildcards Provider<ViewModel>>) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
val creator = creators[modelClass] ?: creators.entries.firstOrNull {
modelClass.isAssignableFrom(it.key)
}?.value ?: throw IllegalArgumentException("unknown model class $modelClass")
try {
@Suppress("UNCHECKED_CAST")
return creator.get() as T
} catch (e: Exception) {
throw RuntimeException(e)
}
}
}

然后我创建了提供 ViewModelFactory 和 ViewModel 的 ViewModelModule,如下所示:
@Module
abstract class ViewModelFactoryModule {

@Binds
abstract fun bindsViewModelFactory(viewModelFactory: ViewModelFactory): ViewModelProvider.Factory

@Binds
@IntoMap
@EbMainScope
@ViewModelKey(EBMainContainerViewModel::class)
abstract fun bindEbMainViewModel(ebMainContainerViewModel: EBMainContainerViewModel): ViewModel

}

在你问之前,这是范围实现:
@Scope
@Target(
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER
)
@Retention(AnnotationRetention.RUNTIME)
annotation class EbMainScope

最后一步,这是我的 Activity/fragment 注入(inject)器模块:
@Module
abstract class ScreensBuildersModule {

@ContributesAndroidInjector
@EbMainScope
abstract fun contributeEbMainActivity(): EBMainActivity

@ContributesAndroidInjector
@EbMainScope
abstract fun contributeEbDashboardMainFragment(): EBDashboardMainFragment

}

当然,我在 AppComponent 中连接了所有内容,并且应用程序运行顺利,但有两个 EbMainContainerViewModel 实例。 ,尽管我定义了范围。

我的解释是,我实际上有两个不同的提供程序而不是一个,但我仍然不明白为什么,因为我将其标记为 @Singleton .

有人对此有解释吗?如果需要更多输入,请告诉我。

最佳答案

我有同样的问题,但用这种方式解决它:

  • 例如,我使用以下代码:
    https://github.com/android/architecture-samples/tree/dagger-android
  • 在我的 fragment (我想在其中使用共享 View 模型)中,我使用
    这(它帮助了我):
    private val viewModel by viewModels<SearchViewModel>({ activity as MainActivity }) { viewModelFactory }

    而不是这个(如示例):
    private val viewModel by viewModels<SearchViewModel> { viewModelFactory }

  • 因为第一个参数是 所有者制作人 ,因此我们在 Activity 范围内创建了一个 ViewModel。

    关于android - 使用 Dagger 跨两个/或多个 fragment 和一个 Activity 共享 ViewModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59342496/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com