Android: MVC?


Android at it’s core is built around a set of components which are combined to produce an application. Android (unlike iOS) is not based around MVC. However with a little magic you can get it working, in light of that here are the basics of MVC.

View


A View under MVC is the part that is shown to the user and usually shows data from the Model. Views never usually interact directly with the Model and usually go via way of the Controller. A View should generally be independent enough that it can be removed and replaced with relative ease.

Controller


The Controller is generally seen as the “glue” between the Model and the View. It is usually where business logic resides or the gateway to the implementation of it. A Controller will also generally be responsible for retrieval of data from the Model which is then passed into the View to be displayed.

Model


The Model is data of the app. It can be a Class or something more complicated. The key point to remember is that it is responsible for data. A Controller generally asks the Model for information about itself to display when the View has asked the Controller.

So that’s a whirlwind tour of MVC I can move onto why Android makes it difficult to implement.

MVC In Android


So what’s the View under Android. I would consider the View to be the XML layout files. They contain the screen items which display information from the Model and are interacted with to send actions to the Controller. Unfortunately it’s not quite that simple.

Android is based around Activities and Fragments. These are in turn responsible for the inflation (showing) of the XML layouts on the screen. Now if that’s all they did I would consider them to also be part of the View, but thats not all they do.

When a button is pressed on the XML layout the “click” action has to go somewhere, that somewhere is usually an Activity or a Fragment. Examples that are given across the web usually give this an example:

Button button = (Button) findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Interact with model here
}
});

Now the problem here is that the logic and Model interactions for the button click is usually placed within the Activity. Logic as previously mentioned should be part of the Controller and as such it could be argued that the Activity/Fragments are both View and Controller at the same time. The Controller and View are therefore usually tightly coupled within and Android application. If for example you needed to replace the button with something else you would have to change the XML file and modify the Activity/Fragment. This would lead to a violation of the Single Responsibility Principle as we have two reasons to change, the XML changes or the click logic changes.

How can we improve this

So the most obvious way to improve this code is to delegate the logic from the Activity/Fragment down into what could be termed a Controller. Your code would probably look something like this:

Button button = (Button) findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
controller.buttonClicked();
}
});

So the logic has been moved down into a Controller class. We will still need a reference to the Controller in the View (Activity) however this should fix the tight coupling problem.

Using this method the View becomes passive and is responsible for simply forwarding actions onto the Presenter. The Presenter is used to format information from the Model and display it using the View.

An Alternative

Looking better, but it’s still nagging at me that the Controller has a reference to the View to update it and the Model would be the same with the controller.

It would be great if we could have a dependency tree which points all one way. So enter Otto an EventBus by Square. An EventBus allows us to listen out for specific Events which interest us and respond as needed.

Say in our previous example the button had attempted to login to some service. We could place the networking/login into the Controller (or a delegate of it) and update the Model with the success or failure of the login. This update would then trigger an Event maybe a LoginSuccessfulEvent/LoginFailureEvent which the View could listen out for. When the View knows the Model has updated it can request the new information from the Controller.

The result of this is a lack of hard dependencies going back up the tree with the dependency arrows pointing inwards, great! This means the system is decoupled and replacing a component shouldn't greatly impact any of the others, leading to a largely modular system.

This is just one approach to a problem with many solutions but I found using Otto to be extremely simple and intuitive. Like everything it has it’s downsides such as; increased code complexity, a “god object” EventBus to name a few. I think the tradoff is worth it for the flexibility given.

Also feel free to take a look at a simple example of this approach here: https://github.com/nhunston/androidmvp

Thanks for reading.