Как Dagger 2 избавляется от введенных полей, когда они больше не нужны? - PullRequest
0 голосов
/ 30 августа 2018

У меня есть вопрос о введении нескольких фрагментов в поля действия. В настоящее время у меня есть такая настройка (все фрагменты расширяют 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 Ответ

0 голосов
/ 31 августа 2018

Я почти уверен, что кинжал не является причиной утечки (если он существовал). То, что делает кинжал, - это просто создание экземпляров участников деятельности с соответствующими экземплярами. Таким образом, вы можете попробовать запустить LeakCarnary с измененным кодом, подобным следующему: lateinit var fragmentOne = FragmentOne() ... и проверить, существует утечка памяти или нет. Возможно, проблема в вашем фрагменте кода.

...