Dagger2/Android:My@FragmentScope子组件在每次旋转时都会被重新创建
最初在Dagger2回购协议上作为 摘要:我有一个活动,其中一个片段具有Dagger2/Android:My@FragmentScope子组件在每次旋转时都会被重新创建,android,dagger-2,dagger,Android,Dagger 2,Dagger,最初在Dagger2回购协议上作为 摘要:我有一个活动,其中一个片段具有setRetainInstance(true)。尽管片段被保留,但每次我对其调用AndroidSupportInjection.inject(this),它都会注入其依赖项的新实例。每次重新创建活动子组件时(旋转时),看起来都在重新创建片段子组件(我想是吧?) 这是预期的,还是我的图形配置错误 我有这样一个应用程序组件: @Singleton @Component(modules = [ AndroidSupport
setRetainInstance(true)
。尽管片段被保留,但每次我对其调用AndroidSupportInjection.inject(this)
,它都会注入其依赖项的新实例。每次重新创建活动子组件时(旋转时),看起来都在重新创建片段子组件(我想是吧?)
这是预期的,还是我的图形配置错误
我有这样一个应用程序组件:
@Singleton
@Component(modules = [
AndroidSupportInjectionModule::class,
ActivitiesModule::class,
AndroidViewInjectionModule::class,
NetModule::class
])
interface MainApplicationComponent {
fun inject(app: MainApplication)
@Component.Builder
interface Builder {
fun build(): MainApplicationComponent
@BindsInstance fun app(app: Context): Builder
// ... other things ...
}
}
活动模块
看起来像:
@Module
abstract class ActivitiesModule {
// ... other things ...
@ActivityScoped
@ContributesAndroidInjector(modules = [
UpgradeActivityModule::class,
UpgradeFragmentModule::class
]) abstract fun upgradeActivity(): UpgradeActivity
}
升级碎片模块
:
@Module
abstract class UpgradeFragmentModule {
@FragmentScoped
@ContributesAndroidInjector(modules = [
UpgradeActivity.UpgradeFragmentModule::class,
ViewInjectorModule::class
]) abstract fun upgradeFragment(): UpgradeFragment
}
和UpgradeActivity.UpgradeFragmentModule
(这都是WIP,很抱歉有奇怪的名称):
@模块
抽象类升级碎片模块{
@绑定@FragmentScope抽象趣味bindUpgradeModel(模型:UpgradeModel):UpgradeMvp.model
@绑定@FragmentScope抽象趣味bindUpgradePresenter(presenter:UpgradePresenter):UpgradeMvp.presenter
//…其他事情。。。
@模块
伴星{
@提供@JvmStatic fun ProviderSources(activityProvider:Provider):资源{
返回activityProvider.get().resources
}
//…其他事情。。。
}
}
我做了进一步的实验,试图让我的@fragmentscope
元素直接继承我的@Singleton
应用程序组件,但它也有同样的问题。事实上,如果我只是连续注入片段两次,每次都会得到新的实例。很明显,我做错了……我强烈建议您只需看看Dagger Android,因为只有少数几个类完成了所有工作
[…]每次我调用AndroidSupportInjection.inject(this)时,它都会注入其依赖项的新实例。看起来正在重新创建片段子组件[…]
这正是发生的事情。
为了给出一个不准确和简化的摘要,您在一个映射中注册了子组件.Builders,当您调用AndroidInjection.inject()
时,它将查找并创建正确的生成器和组件,然后用它们注入对象
您不应该多次注入对象,因为在最好的情况下这将一事无成,否则将导致错误/bug。作用域是每个组件的,因此,如果重新创建该组件,则会同时重新创建其作用域内的每个对象。调用AndroidInjection.inject()
将始终创建一个新组件
您不会详细说明何时何地注入内容,但如果您保留相同的片段对象,则不应再次注入它 […]并试图使我的@FragmentScope元素直接成为我的@Singleton应用程序组件的后代,但它也有同样的问题 这就是你应该做的。如果使用
setRetainInstance(true)
,则片段很可能不是升级活动的子组件,否则在重新创建活动时会泄漏引用
如果我只是连续注入片段两次,每次都会得到新的实例
如果您调用
AndroidInjection.injection()
,那么每次调用它都会创建一个新组件,所以我假设这就是您所做和观察到的。如果使用同一组件两次注入对象,则任何作用域对象都将是相同的。每次使用都将始终创建非范围对象。但是在任何情况下,都不应该多次注入对象。我试图第二次不注入保留的片段,但最终泄漏了活动。不知怎的,dagger.android中的一个类保留了一个引用。我将重新创建场景并发布stacktrace。不过,你的解释似乎是正确的!无论是什么原因导致了泄漏,我似乎已经解决了我的匕首组件摆弄了一点。我想我在某处注射了一个活动参考,但我已经摆脱了它。FWIW,在dagger.android
之前,我曾经保留对我的子组件的静态引用,而不是对我的构建器的静态引用,所以我错过了这个技巧。世界又有意义了!
@Module
abstract class UpgradeFragmentModule {
@Binds @FragmentScoped abstract fun bindUpgradeModel(model: UpgradeModel): UpgradeMvp.Model
@Binds @FragmentScoped abstract fun bindUpgradePresenter(presenter: UpgradePresenter): UpgradeMvp.Presenter
// ... other things ...
@Module
companion object {
@Provides @JvmStatic fun provideResources(activityProvider: Provider<UpgradeActivity>): Resources {
return activityProvider.get().resources
}
// ... other things ...
}
}