In this post, I would like to write about a frequently asked question, which is, “should/can you use AAC-ViewModel for MVP’s Presenter?”. Before we jump to conclusions, let’s quickly have a look at what AAC-ViewModel is made of and how it works.
Internals of AAC-ViewModel
Here is the list of files used by AAC-ViewModel (alpha-9).
Out of these, I would like to talk about 2 really important classes.
ViewModelStore is a simple HashMap of ViewModel, which is used to store the viewModel(s) instance(s) as long as they are needed and then removed when not needed anymore.
HolderFragment is AAC-ViewModel’s most important element & here are some of it’s main responsibilities.
- It maintains a Map of view context(s) (activity/fragment) & a HashMap of viewModel(s) using an instance of ViewModelStore, thus providing storage space for both.
- It adds a new instance of a UI-less HolderFragment, which is a retained fragment and this is how it survives through configuration changes.
- It also keeps an eye on given view context’s lifecycle and when the view context’s onDestroy() method gets called, it performs the following auto cleanup actions,
- Call onCleared() method of the viewModel(s), if needed
- Remove the view context from the Map
- Remove viewModel(s) from ViewModelStore’s HashMap
So, in short AAC-ViewModel does 3 main things, it is lifecycle aware + it is a data storage factory, which survives configuration changes + it performs auto cleanup when needed, without manual intervention.
Now that we know how AAC-ViewModel works and the key roles it performs, let’s look at the question at hand.
Using AAC-ViewModel for MVP’s Presenter
At first it may feel tempting to use AAC-ViewModel to store presenter, by having a presenter extending AAC-ViewModel, so that it can survive configuration changes, because it is way easier to implement in comparison with Loaders or other third party libraries, but,
Should you use AAC-ViewModel for MVP’s Presenter?
- You will end up using AAC-ViewModel just for the Storage Factory aspect of it and loose the whole auto clean up thing. How? because even after using AAC-ViewModel, your Presenter would still need the view reference and the view would still need to manually bind and unbind the presenter, so there goes the auto clean up. And without the auto clean up feature, AAC-ViewModel is not worth it. Good old retained fragment would be a better choice in that case.
- And one of the reasons why AAC-ViewModel works well with MVVM and not with MVP is because the core principle of AAC is that, a LifecycleOwner (Activity/Fragment/Custom View) entity’s job is to provide Lifecycle events and use the functionalities provided by LifecycleObserver(s) (ViewModel/LiveData/Custom Observer) & don’t have to worry about Observer side cleanup. It is LifecycleObserver’s job to manage & cleanup itself based on the Lifecycle events. This is possible with MVVM and not with MVP. So it looks like AAC wasn’t designed after selecting MVVM, but once it was designed MVVM was an obvious choice.
Can you use AAC-ViewModel for MVP’s Presenter?
Yes, you can.
- There are cases where AAC-ViewModel would still be useful even if you use it for Storage Factory, e.g. If you can’t (or don’t want to) use a retained fragment or you don’t want to use Loaders or other storage solutions over really simple AAC-ViewModel. In that case why not?
- So, if you decide to use it, pay extra attention when handling view reference(s), to not cause a memory leak, and it will work like a charm.
AAC’s ViewModel and LiveData manage and cleanup themselves automatically based on AAC-Lifecycle events. That is why they work seamlessly with MVVM, but if you wish to use them with other architectures like MVP then be ready to do manual cleanups on your own.
Hope it helps, Let me know what you think & if you have any suggestions.