Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dagger2 scopes and activity lifecycle

I have an Android Activity that I'm using Dagger2 to inject a Presenter into. I'd like my Presenter to be capable of holding state even if a configuration change occurs.

For instance, I'm going to use the Presenter to kick off a network call and if the user rotates the device while the network call is in-flight I'd like to be able to receive the response after the device finishes its rotation and not have to restart the call.

I'm getting tripped up because if I scope the instance of Presenter to the Activity's life, then isn't there a chance that the Presenter would be garbage collected when the Activity goes through onDestroy() during a configuration change? My other thought was to use a scope that is valid during the life of the application. However, if I do that how do I ensure that my Presenter can be garbage collected once the Activity has been destroyed for good (not due to a config. change, but something like the back button being pressed)?

Is there a way to ensure that my Presenter will survive an Activity's configuration change and also not be leaked for the life of the Application?

like image 778
neonDion Avatar asked Jan 25 '17 02:01

neonDion


1 Answers

I would strongly advice against trying to implement this approach.

You're effectively trying to use DI framework in order to support Activity specific life-cycle flow, although DI frameworks are not intended to be used like this.

I recently answered another similar question in which OP tried to share state in View-Model between different Activities. Although use cases are not identical, the general pattern is the same - attempt to delegate flow control responsibilities to DI framework, which is not a good idea.

The best approach in your case (IMHO) would be to store the current state before rotation, re-instantiate the presenter upon rotation, and then restore its state.

How you store the state during rotation depends on what exactly you're trying to preserve:

  • If you need to preserve UI related state (selections, texts, position of elements, etc.) then you can use the usual onSaveInstanceState() and onRestoreInstanceState() callbacks
  • If you need to preserve some business related state (ongoing network requests, data, data modifications, etc.) then encapsulate this logic in a business class (e.g. SomeBusinessUseCaseManager) and inject this class from Application wide component with a scope.

You can find a detailed review of Dagger's scopes here.

More information about DI in Android can be found here.

like image 76
Vasiliy Avatar answered Sep 21 '22 15:09

Vasiliy