Dagger 2 如何处理不再需要的注入字段?
How does Dagger 2 dispose of injected fields when they are no longer needed?
我对将多个片段注入 activity 的字段有疑问。目前我有这样的设置(所有片段都扩展 DaggerFragment 并且 activity 是 DaggerAppCompatActivity):
@Inject
lateinit var fragmentOne: FragmentOne
@Inject
lateinit var fragmentTwo: FragmentTwo
@Inject
lateinit var fragmentThree: FragmentThree
override fun onCreate(...) {
...
startFirstFragment()
}
fun startFirstFragment() {
supportFragmentManager.beginTransaction()
.replace(containerId, fragmentOne).commit()
}
fun startSecondFragment() {
supportFragmentManager.beginTransaction()
.replace(containerId, fragmentTwo).commit()
}
一切正常,直到我添加 LeakCanary,它表示,当我用第二个片段替换第一个片段时,被替换的实例会通过 lateinit var fragmentOne
泄漏,因为它保留了对第一个片段的引用。我的问题是:dagger 什么时候清空字段,它是否正确地清空字段,谁应该受到责备:dagger 导致泄漏,LeakCanary 用于误报泄漏检测或其他?
应用程序组件:
@ApplicationScoped
@Component(
modules = [
AndroidSupportInjectionModule::class,
ActivityBindingModule::class,
ApplicationModule::class,
RepositoriesModule::class,
NetworkModule::class]
)
interface ApplicationComponent : AndroidInjector<MyApp> {
override fun inject(instance: MyApp?)
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): ApplicationComponent
}
}
ActivityBindingModule:
@Module
abstract class ActivityBindingModule {
...
@ActivityScoped
@ContributesAndroidInjector(modules = [ActivityInQuestionModule::class])
internal abstract fun aiqActivity(): ActivityInQuestion
@ActivityScoped
@Binds
internal abstract fun fragmentSwitcher(activityInQuestion: ActivityInquestion): FragmentSwitcher
}
ActivityInQuestionModule:
@Module
abstract class ActivityInQuestionModule {
@FragmentScoped
@ContributesAndroidInjector
internal abstract fun fragmentOne(): FragmentOne
@FragmentScoped
@ContributesAndroidInjector
internal abstract fun fragmentTwo(): FragmentTwo
@FragmentScoped
@ContributesAndroidInjector
internal abstract fun fragmentThree(): FragmentThree
}
我很确定匕首不是泄漏的原因(如果它存在的话)。 dagger 所做的只是用适当的实例实例化 activity 的成员。所以你可以尝试 运行 LeakCarnary 修改代码如下: lateinit var fragmentOne = FragmentOne() ...
并验证是否存在内存泄漏。也许问题出在您的片段代码中。
我对将多个片段注入 activity 的字段有疑问。目前我有这样的设置(所有片段都扩展 DaggerFragment 并且 activity 是 DaggerAppCompatActivity):
@Inject
lateinit var fragmentOne: FragmentOne
@Inject
lateinit var fragmentTwo: FragmentTwo
@Inject
lateinit var fragmentThree: FragmentThree
override fun onCreate(...) {
...
startFirstFragment()
}
fun startFirstFragment() {
supportFragmentManager.beginTransaction()
.replace(containerId, fragmentOne).commit()
}
fun startSecondFragment() {
supportFragmentManager.beginTransaction()
.replace(containerId, fragmentTwo).commit()
}
一切正常,直到我添加 LeakCanary,它表示,当我用第二个片段替换第一个片段时,被替换的实例会通过 lateinit var fragmentOne
泄漏,因为它保留了对第一个片段的引用。我的问题是:dagger 什么时候清空字段,它是否正确地清空字段,谁应该受到责备:dagger 导致泄漏,LeakCanary 用于误报泄漏检测或其他?
应用程序组件:
@ApplicationScoped
@Component(
modules = [
AndroidSupportInjectionModule::class,
ActivityBindingModule::class,
ApplicationModule::class,
RepositoriesModule::class,
NetworkModule::class]
)
interface ApplicationComponent : AndroidInjector<MyApp> {
override fun inject(instance: MyApp?)
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): ApplicationComponent
}
}
ActivityBindingModule:
@Module
abstract class ActivityBindingModule {
...
@ActivityScoped
@ContributesAndroidInjector(modules = [ActivityInQuestionModule::class])
internal abstract fun aiqActivity(): ActivityInQuestion
@ActivityScoped
@Binds
internal abstract fun fragmentSwitcher(activityInQuestion: ActivityInquestion): FragmentSwitcher
}
ActivityInQuestionModule:
@Module
abstract class ActivityInQuestionModule {
@FragmentScoped
@ContributesAndroidInjector
internal abstract fun fragmentOne(): FragmentOne
@FragmentScoped
@ContributesAndroidInjector
internal abstract fun fragmentTwo(): FragmentTwo
@FragmentScoped
@ContributesAndroidInjector
internal abstract fun fragmentThree(): FragmentThree
}
我很确定匕首不是泄漏的原因(如果它存在的话)。 dagger 所做的只是用适当的实例实例化 activity 的成员。所以你可以尝试 运行 LeakCarnary 修改代码如下: lateinit var fragmentOne = FragmentOne() ...
并验证是否存在内存泄漏。也许问题出在您的片段代码中。