I have a question about injecting multiple fragments into the activity's fields. Currently I have such a set up (all fragments extend DaggerFragment and the activity is 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()
}
And everything works fine, until I add LeakCanary, which says that, when I replace first fragment with the second, the instance being replaced leaks through lateinit var fragmentOne
as it retains the reference to the first fragment. My question is: when does dagger empty the fields, does it do it correctly and who is to blame: dagger for causing leaks, LeakCanary for false positive leak detection or something else?
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
}
I'm pretty sure that dagger is not the reason of leak (if it's existed). What dagger do is just instantiating members of activity with appropriate instances. So you can try to run LeakCarnary with code modified like this: lateinit var fragmentOne = FragmentOne() ...
and verify if memory leak exists or not. Maybe the problem is in your fragments code.