Android Architecture with Multi-Screen MVP (Part 1)

Chryssa Aliferi
Beat Engineering Blog
5 min readSep 21, 2016

--

Ιn the Android Taxibeat team, we have always found ourselves in a constant “fight” of maintaining our ever growing code, trying to solve the emerging problems of an Android project that started literally from a few Android Activities and exploded into a project with more than 200.000 lines of code. Android’s standard architecture isn’t always capable of addressing the challenges of complex projects. This is why we needed to figure out how to develop our production code to a more stable base. This journey was long and, of course, will continue to be. But for now, let’s take a “ride” to explore the Android Architecture that our app is based on today.

Old-school Taxibeat Android:

In older Android Taxibeat times, our team followed the classical way of developing Android applications, employing the canonical Android framework separation.

This translated into POJO’s as Models, XML layouts as the Views and Activities (as well the Fragments) as both Controllers and Presenters at the same time, in an attempt to model the POJO’s and to present them in a complex UI with many animations and newnesses.

Well, not for long… Soon enough we realised that the Activities had too many responsibilities and were tightly coupled not only with their views but also with the business logic. As our codebase became wider, every little change in the POJO’s could end up in redesigning the controls of our views, and likewise, every little UI enhancement resulted in the reimplementation of the business logic parts of our codebase.

The greatest challenge we wanted to address, however, was the need to make our code more testable. Yet, this wouldn’t be possible in a complex codebase with hard dependencies within its Activities. Furthermore, different testing tools require different approaches. Unit tests, based on JUnit, need to run over clean Java code, and Espresso tests functional user interface (UI) over Android framework.

Model View Presenter era.

After consideration, we decided to rethink the way we produced our Android code. We decided to completely separate the application views from the business logic. Enter the Model-View-Presenter (MVP) architectural pattern.

MVP introduces only three main elements, Views, Presenters and Models:

The Model layer represents a set of classes that define the data. It also defines business rules for data, so that it can be transformed and manipulated.

The View layer represents the UI components and transforms the information contained by the model into the UI.

The Presenter is responsible for handling all UI events on behalf of the view. It retrieves data from the Model layer and after the right transformations, formats the data for display in the View.

There are many articles all over the Internet that explain in detail not only the definition of MVP, but also suggest numerous alternatives. What they typically fail to address, however, is what exactly Model, View and Presenter definitions mean when it comes to architecting an Android application.

Let’s see this differently.

Suppose, that we could forget for a moment all the technical restrictions, and discuss about View and Presenter layer.

One typical misconception when referring to the View is the perception that a View is typically associated with a single Activity. What if we adopted the concept of a “Screen” and used that instead of the View in the same context? How many Screens can you “count” inside a single Activity? Or, as a corollary, to how many Screens could an Activity’s XML layout be transformed in?

Another misunderstanding in MVP, is the misconception that every View has a single Presenter, tightly coupled in a one-to-one relationship. In other words, that a Presenter is connected with the business logic of a single Activity. What if we could try to replace Presenters with the “Flows”, that actually control the flow of the Application? How many business logic Flows can you detect in an Activity?

Let’s try dealing solely with Screens and Flows from now on as an experiment!

So, how to implement multiple Screens and Flows on an MVP pattern?

Our experiment in a real example:

Recently we launched a completely redesigned version of our Android Taxibeat app, which we thoroughly re-engineered in order to implement a very demanding UI/UX change. Our main goal was to give the users the impression, that every action they make derives from the main map of the application.

Many animations and complex views were designed in order to succeed in delivering the most fluid UI experience we could. Having that in mind, we decided that we are going to conceptually separate our application into many different “Screens”, regardless of any the technical restrictions.

In the main map of the application we could detect the the “PickupLocation screen”, the “TripDetails screen” and the “CallingATaxi screen”. All of them were sharing the same UI components and were tied in with fluid animations.

PickupLocation screen and TripDetails screen, in the same Activity

However, the technical specifications suggested that, because of the complex animations, everything should happen inside a single Activity the contains our basic MapFragment.

Taking that into consideration, we tried to figure out, how we could meld one or more of these Screens under the same UI, keeping our code neat while producing the desired UX. We came across the Presenters, with every Presenter to be capable to control the flow of each Screen. These Presenters were our Flows.

We ended up having, several Screens and Flows contained within a single Activity. For example, our MainActivity that implements the main map of the application, supports the “Menu screen”, the “PickupLocation screen” and the “TripDetailsLocation screen”, along with their implementations of “MenuFlow”, “PickupLocationFlow” and “TripDetailsFlow”.

To be continued…

Having explained the theory behind our MVP alternate implementation, in the second part of this article, we are going to demonstrate in code the structure and format of this architectural pattern.

However, when designing an Android application, always keep in mind that choosing an architectural design may entail adhering to a certain conventions, but may also require substantial deviations from the norm in order to address specific needs.

--

--