Programming for Android may be tricky due to several reasons. One of them is the poor separation of concerns. If some experienced developer is used to coding the “clean” way and now moves to Android, he may be quite confused by the relative mess of the native components inside. Often the Activities, Adapters or Fragments have to mix application logic, data access and presentation within because Android's architecture doesn’t offer any effective mechanisms to separate them. The result is a loosely coupled, arduously extendable application which is vulnerable to errors, hard to test as well as maintain. Fortunately, Android's development doesn’t stand still and more new patterns and interpretations of the old ones are appearing to make a developer’s life easier. We’re going to talk about one of them, the MVP pattern.
Typical application of architecture on Android
A user interacts with Fragment or Activity, that represents a logical part of the screen (in most cases the whole screen). In almost all examples from Google/Android developers it is easy to see that business logic lies within that Fragment or Activity which seems kind of wrong. If you want to perform some asynchronous operation, you have to handle multiple edge cases like screen rotation, application minimization and so on.
What is MVP
Model View Presenter (MVP) is an architectural pattern that derives and inherits most properties from the Model View Controller pattern. The main difference is the responsibility of the middle layer - presenter/controller. While the controller defines behavior and typically has multiple views that are controlled by it, the presenter in most cases has a one to one relationship with its view. The other difference is that the view in MVC can communicate directly with the model but in MVP the presenter is responsible for all “communication” between the view and the model.
The view is a rendering layer that shows information to the user and all input events like button clicks, text insertion, passes to presenter, etc.
The presenter is responsible for processing the view input events and for querying data from the model. When data arrives to the presenter, it is processed there and bound to view.
The model is everything that we can imagine with data sources - API, Database, files, etc. The model is responsible for retrieving data and can be responsible for listening to data changes (like in a database) and inform the presenter about it.
Android and MVP
We have used one of the many approaches on how to apply an MVP pattern to Android that is used by many other developers. The abstract diagram is shown on the next diagram.
The view is typically with Activity or Fragment (but can also be a custom Android View class). Any of these classes should implement the interface, that is defined for this view. The presenter doesn't know what implementation lies behind this interface so the developer can easily decide if he wants to switch to Activity from Fragment for example. The only responsibility of this view is showing data and passing UI events to the presenter. This is the main difference from the classical Android application architecture, where all logic lies in Activity/Fragment code and is dependent on its state.
This View has instance of Presenter class and is responsible for creating it. The ideal state is when the presenter's instance lives for the whole time the Activity/Fragment is used by the user, even in backstack. The instance of the presenter should be destroyed and freed when the user leaves this “screen” and it's impossible to come back to this screen.
What is specific to Android is that View doesn't have to be attached to the presenter the whole time the presenter is living (device rotation, application is in the foreground, etc.). Therefore, the View has to connect/disconnect itself to the presenter. In Fragment or Activity it's typical to manage that with onResume/onPause methods.
I've created a simple application that simulates user login. You can see two different approaches
- LoginActivity which is generated by Android Studio and contains all logic inside
- The same code as in 1) but re-used with the MVP pattern.
The source codes https://github.com/AckeeCZ/MVPexample.
We've introduced the MVP pattern and its implementation on the Android platform. In the sample application the differences are shown between the typical architecture and the MVP architecture in login use case.
In the next article, we will show you multiple approaches to MVP, different libraries and share our experiences with them.