Android has never been so pleasant to work with: Jetpack and Architecture Components improved our lives in so many ways introducing easy ways to deal with Lifecycle, state retention and so many other common tasks that are part of every day’s Android Developer work.

One of the most popular ones is ViewModel which is the main component of Google’s Guide to App Architecture for Android together with LiveData.

What is so good about ViewModels?

Easy to retain state/instance

What is not so nice about ViewModels?

Extremely poorly named

Forced inheritance

onCleared callback

callback Factory to use custom constructors

Wouldn’t it be nice if we could get the advantages without the not so nice features?

TL;DR: The code can be found in this GIST.

ViewModel is a Retained Instance

What if I tell you that ViewModel is just a "retained instance" and any class, independent of your architecture, could use a ViewModel to retain state? This is clearly stated on Activity 1.0.0 release notes:

It is strongly recommended to use ViewModels to store non-configuration state…

What if we ignore the name and reimagine ViewModels as a simple way of retaining any instance?

Dagger Components as a ViewModel — Arch Component

Before we start, let's add Android-KTX libraries and Dagger dependencies to build.gradle :

To make it easier to work with, let’s define a better naming for our ViewModels and few small delegate functions that will be responsible for creating those components.

Then, it is time to define our Dagger Component and scope it per Activity:

Here we have some new concepts: Instead of using the normal approach and defining our Dagger Component as an Interface, we'll need to use an abstract class and inherit from ScopedComponent : ViewModel .

@Component: Annotates an interface or abstract class…

Now, to test our setup let's define a few classes: a Presenter scoped per Activity that has a reusable Repository dependency and a single Int field called counter , that will be the state we will preserve on configuration changes.

Now it is time to glue everything together.

That’s it. If you run this code and rotate the screen of the device you will see that the counter state will be preserved.

Conclusion

With few lines of code we manage to preserve Dagger Components in Configuration Changes, allowing us to scope our components based on the Activity lifecycle and getting the following advantages:

Use whatever name you want

No inheritance

No factory

Happy coding! 😎