I've written a sample app to familiarize myself with Dagger Android. I have 2 activities with a simple fragment each, a Main Activity that has a button to launch a Details activity, which has a button that just finishes the activity. What I see is that when I finish the Details activity, it is still in memory, and every time I click the button to go to Details, a new instance is created (as expected), but not released when exiting.
I have defined the Dagger modules as follows:
AppComponent:
@Component(modules = [AppModule::class,
AndroidSupportInjectionModule::class,
BuilderModule::class,
StorageModule::class])
@ApplicationScope
interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: DaggerSampleApp): Builder
fun build(): AppComponent
}
fun inject(app: DaggerSampleApp)
}
AppModule:
@Module(subcomponents = [MainActivitySubComponent::class,
MainFragmentSubComponent::class,
DetailActivitySubComponent::class,
DetailFragmentSubComponent::class])
@ApplicationScope
class AppModule {
@Provides
@ApplicationScope
fun provideContext(application: DaggerSampleApp): Context {
return application.applicationContext
}
}
BuilderModule:
@Module
@ApplicationScope
abstract class BuilderModule {
@Binds
@IntoMap
@ActivityKey(MainActivity::class)
abstract fun bindMainActivityInjectorFactory(builder: MainActivitySubComponent.Builder): AndroidInjector.Factory<out Activity>
@Binds
@IntoMap
@FragmentKey(MainFragment::class)
internal abstract fun bindMainFragmentInjectorFactory(builder: MainFragmentSubComponent.Builder): AndroidInjector.Factory<out Fragment>
@Binds
@IntoMap
@ActivityKey(DetailActivity::class)
abstract fun bindDetailActivityInjectorFactory(builder: DetailActivitySubComponent.Builder): AndroidInjector.Factory<out Activity>
@Binds
@IntoMap
@FragmentKey(DetailFragment::class)
internal abstract fun bindDetailFragmentInjectorFactory(builder: DetailFragmentSubComponent.Builder): AndroidInjector.Factory<out Fragment>
}
Details Activity component:
@ActivityScope
@Subcomponent(modules = [DetailActivityModule::class, BitmapCacheModule::class])
interface DetailActivitySubComponent : AndroidInjector<DetailActivity> {
@Subcomponent.Builder
abstract class Builder : AndroidInjector.Builder<DetailActivity>()
}
Details Fragment component:
@ActivityScope
@Subcomponent(modules = [DetailFragmentModule::class, BitmapCacheModule::class])
interface DetailFragmentSubComponent : AndroidInjector<DetailFragment> {
@Subcomponent.Builder
abstract class Builder : AndroidInjector.Builder<DetailFragment>()
}
Details activity:
class DetailActivity : AppCompatActivity(), HasSupportFragmentInjector {
@Inject
lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
@Inject
lateinit var appContext: Context
@Inject
lateinit var prefs: Prefs
@Inject
lateinit var bitmapCache: BitmapCache
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_detail)
if (savedInstanceState == null) {
supportFragmentManager
.beginTransaction()
.replace(R.id.container, DetailFragment.newInstance(), DetailFragment.FRAGMENT_TAG)
.commit()
}
}
override fun supportFragmentInjector(): AndroidInjector<Fragment> {
return fragmentDispatchingAndroidInjector
}
}
Details fragment:
class DetailFragment : Fragment() {
@Inject
lateinit var appContext: Context
@Inject
lateinit var prefs: Prefs
@Inject
lateinit var bitmapCache: BitmapCache
override fun onAttach(context: Context?) {
AndroidSupportInjection.inject(this)
super.onAttach(context)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_detail, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
view.findViewById<Button>(R.id.button).setOnClickListener {
activity?.finish()
}
}
companion object {
const val FRAGMENT_TAG = "main_fragment"
fun newInstance() = DetailFragment()
}
}
So why is the Details activity not released?

OnClickLIsteneris maintaining a reference toActivityrather than getting it viathis.getActivity()- David Rawson