2020 Guide to Implementing Model-View-Presenter Architecture in Android
Outlining the considerations and concerns for a high-quality MVP architecture.
Model-View-Presenter(MVP) is a humble architecture pattern that has become the de-facto architecture pattern until Model-View-ViewModel(MVVM) was introduced by Google. MVP still holds a lot of merit against the newer and shinier MVVM.
The view and model in both cases have the same responsibilities and qualities. The primary differences are between the architectures presenter and the view-model. Let’s examine the two side by side.
The presentation components may embody different qualities but they share the same responsibility of being the middle man between the view and model.
This article will go over the various considerations and concerns you should think about as you implement an MVP architecture. As a bonus, I will include examples addressing each of those points.
Android Concerns
When we talk about implementing a presenter in Android there will be a few things we have to think about.
Lifecycle
The Android lifecycle is something the presenter will have to be passively aware of and will dictate the attachment and detachment to the view.
Presenter State
The requirement for state persistence will enable the screen to be able to recreate itself in the case of configuration changes or process death.
View Components
The view component of MVP is commonly implemented by the Activity, Fragment, and View. Our architecture solution should support any of these Android classes as the view component.
Implementation Example
So let’s look at all of these components through an example.
The view is pretty self-explanatory. It knows about the presenter.
This presenter fulfills the attach & detach feature. It has access to a persistence store through RetainedState
. It has no Android dependencies making it easier to test. The @CallSuper
annotation will remind all child classes to call the super method to preserve the proper execution chain.
RetainedState is a very simple Android-specific persistence store. SavedStateHandle
is backed by a Bundle
so beware of the 1mb data limit or else you’ll be seeing TransactionTooLargeException
. If you are saving a lot of information, you may want to consider SharedPreferences
or a database solution.
The MVPLifecycleObserver
is the class that connects everything together and helps deliver the view and persistence component to the presenter.
Pet Adoption Example
We’ve talked about the various infrastructure pieces of our MVP architecture implementation. Let’s dive into how it is used in a Pet Adoption example.
The fragment is responsible for retrieving the presenter. This part can be handled by your DI framework. The RetainedState
will also be generated by the fragment as it is a ViewModel
. The last thing the fragment has to do is create the MVPLifecycleObserver
and attach it. That’s all the setup code needed!
The presenter will generally override the view attach/detach hooks and add the appropriate logic.
Check out the full example project in the link below.
Closing Thoughts
I have outlined a few of the most important considerations one should think about when implementing an architecture pattern in Android. In the MVP architecture example, we’ve proven that we can accomplish creating a solution that is simple, has minimal boilerplate code, and easy to test.
MVP is still a solid option in the Android architecture space.
Bonus Topic: Addressing Giant Presentation Components
If your Presenter or ViewModel grows to become a big class with many lines code, you can check out my article on how to refactor them into smaller pieces and connect them with the mediator pattern.