MVI Architecture with Android

The application lifespan is tied to its flexibility to scale for that it needs a solid base that’s why for every project the most important step is to create the app architecture, after a good long discussion with the technical team about defining the elements included in the system, the functionality of each element and how they will be communicating with each other, we have to put a clear design of the overall architecture.
There are different architectures for android applications, from what I’ve experienced the last years the MVVM and the MVI architecture are the most common architectures used for large scale applications, even for each of them there is no one way to be implemented and it depends on the application needs, also the developers' styles that worked on it, cause I believe that independently of the Android framework every developer has their unique experience in software development and what they bring to the table is not only their knowledge but also their special way of thinking, problem-solving and designing code.
Why MVI?
With no clear state management, view rendering along with the business logic can get a little bit messy as the application grows or adding functionalities or a feature that was not planned beforehand, and let’s be honest that can happen often, it’s rare to have all the features clearly and fully defined from the start of the project specifications, the more the app codebase is scalable the more it’s flexible to embrace new ideas and updates.
The business logic and the UI rendering get tangled as a result of the state crises, how that happens? well:
- The Presenter/ViewModel has his own state
- The business logic produces its own state
- Trying to Synchronising both of the above states
- If there are no clear management of the inputs to the Presenter/ViewModel -> results of tangles processed outputs-> messy business logic and View rendering -> code smells like the Fragment/Activity become a black hole class (by attracting more responsibilities) or having divergent classes ( when you want to make an update but you have to change a class in many different ways for many different reasons) and that results from a poor separate of concern.
What’s the benefit of adapting the MVI architecture pattern :
- State management using immutability to have a single source of truth.
- Unidirectional data flow
- reproducible state -> simple code reuse
- better separation of concern -> maintainability
Breaking down the layers
MVI stands for Model-View-Intent :
- Model: instead of having a separate state for the View, ViewModel, and the Data layer, the Model will be the single source of truth of the overall state, and it’s immutable to ensure that it will be updated from only one place.
- View: represent the UI layer, the activity, or the fragment, it defines the user actions and renders the state emitted by the model.
- Intent: do not confuse it with the Android Intent, it’s the intention to perform an action either by the user or the app itself.

Relying on functional programming each layer get input and feeds the next layer with its output, mathematically we expect the function f(x) to have the same resulted output for the same x input, applying this logic using immutable data and represent it with sealed classes in Kotlin( yes sealed classes will become your best friend in MVI architecture)
So let’s have a closer look at each layer and talk in more details about their interaction with each other:
Model
The definition of Model in other architecture like MVP or MVVM is different, the Model in previous patterns is it the data layer and the domain layer that represents the bridge between the app and the remote data source.
In MVI pattern, the model is also the data but represented as an immutable state, it means that the state will be updated in only one place in the app, which is the business logic, and that will ensure that the state won’t be changed in no other place in the app, therefore the business logic is the single source of truth that create the immutable Model.
That’s how the state will be represented, a sealed class that holds the data:







