Как Dagger 2 избавляется от введенных полей, когда они больше не нужны?
У меня есть вопрос о введении нескольких фрагментов в поля деятельности. В настоящее время у меня есть такая настройка (все фрагменты расширяют DaggerFragment, а действие - 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
так как он сохраняет ссылку на первый фрагмент. Мой вопрос: когда кинжал очищает поля, делает ли он это правильно и кто виноват: кинжал за утечку, LeakCanary за ложно-положительное обнаружение утечки или что-то еще?
ApplicationComponent:
@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
}
1 ответ
Я почти уверен, что кинжал не является причиной утечки (если она существовала). То, что делает кинжал, - это просто создание экземпляров участников деятельности с соответствующими экземплярами. Таким образом, вы можете попробовать запустить LeakCarnary с измененным кодом следующим образом: lateinit var fragmentOne = FragmentOne() ...
и проверьте, существует ли утечка памяти или нет. Возможно, проблема в вашем фрагменте кода.