I'm new to Dagger2 dependency injection. I have some difficulties to retain the same component when screen is rotated.
@Inject
MainActivityPresenterImpl presenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
component = DaggerMainActivityComponent.builder()
.mainActivityModule(new MainActivityModule(this))
.applicationComponent(TrainningDagger3.get(this).getComponent())
.build();
component.inject(this);
presenter.fetchData();
}
I tried to debug the application and I think when new configuration is loaded its creating new instance of component and new instance of the presenter. How I can retain the same component and presenter when screen is rotated. Thank you so much!
You're going to have to decide whether you want your Activity to be destroyed and recreated when the screen rotates (i.e. "the configuration changes"). If you want to handle it yourself, which I recommend, you simply make the change in your AndroidManifest.xml; if you want to handle it through Dagger, you're going to need to save your data in a longer-lived object (such as your ApplicationComponent).
As in the official docs on "Handling Configuration Changes", you can instruct your Activity to simply handle a method call instead of being restarted:
<activity android:name=".MyActivity" android:configChanges="orientation|keyboardHidden" android:label="@string/app_name">
Now, when one of these configurations change,
MyActivity
does not restart. Instead, theMyActivity
receives a call toonConfigurationChanged()
. This method is passed aConfiguration
object that specifies the new device configuration. By reading fields in theConfiguration
, you can determine the new configuration and make appropriate changes by updating the resources used in your interface.
Importantly, this allows you to keep your ActivityComponent exactly as long-lived as your Activity itself, and can reason better about when your Activity's instance is valid or stale. You will still need to take care of loading and saving your data for Android's multitasking, but that is true no matter how you use Dagger.
If you think it is important to destroy and recreate your Activity on a configuration change, that's fine, but I would caution against using the term "activity component" if your are creating or modifying a component to live longer than a single Activity instance. That would be an atypical usage of the term, and might be very confusing for other developers. Instead, if you want a Dagger component to create and hold state for multiple Activity instances (of multiple activity classes, or multiple instances of the same activity), you should consider putting those objects into your existing ApplicationComponent, or creating a new component (e.g. "SessionComponent") that lives longer than one ActivityComponent but shorter than your ApplicationComponent. If you do this, you'll need to be very careful that nothing in this object holds onto an Activity instance, View, or anything that is permanently associated with a single Activity: That would cause a memory leak, as Android would not be able to garbage-collect those pieces of the Activity while your SessionComponent or ApplicationComponent holds a reference to it.