Explain like I am Junior II -Android Architecture

Hadi Tok
6 min readJan 7, 2019

First part of the series about Support library and Google Play services is here:

Selimiye Mosque in Edirne

Architecture used on the Android apps changed a lot through the years, it is hard to catch even up for senior developers. We have MVC, MVP, MVVM, MVI and others on the architecture side and we have Dagger, Dagger 2 and with Kotlin we have Koin and Kodein as Dependency Injection (DI) frameworks. But what should we use? Which is the best? I may not have answer but I will try to explain why we use them.

I think having architecture does two things:

  • Arrange the code in between isolated layers (called layers of abstraction)
  • Interaction between the layers

Different architectures do these two things differently. MVx Architecture Patterns and Dependency Injection is commonly used on Android and I will talk about them.

MVx Architecture Patterns

If we look at names of MVC, MVP, MVVM and MVI architectures we would see that they have MV common in them and the last part is different. Based on this we can say that these patterns they share two of them. Let’s see what they are:

  • Model: It is referring the data that needs to be displayed or acted upon and the layer the data is obtained from which could be a database, a file or an API the data fetched from.
  • View: View is the part where the data is displayed and user interaction is happening.
  • x-Logic: Even though it is slightly different in MVC the logic layer is responsible for converting the data obtained from Model layer to a displayable form by the View layer and converting user actions from the View Layer to changes required at the Model.

Although we abstract same things in the layers, logic layer defines the interaction between them, and it is what makes the difference between MVx architectures. As we can see these architectures have a user facing side and they are used with applications with user interfaces. It is for you to decide to investigate them and pick the one you like but Android Jetpack has support for MVVM with ViewModel and LiveData which I will talk about in the next post.

The architectural patterns have foundation on Separation of Concerns (SoC) principle. By separating the concerns, we can change parts of the code without changing the other parts. I am not saying this important but there are other reasons why we use them on Android. Before explaining them let’s talk about Dependency Injection.

Circassian Dagger

Dependency Injection (DI)

Although Dependency Injection is a scary name, what it is doing is actually simple. Classes requires instances of other classes (dependencies), for example if we want do requests to an API we would need a Retrofit instance. Dependency injection is: instead of creating instances of objects where we use, they are created somewhere else and provided to where is needed. If we don’t use DI and want to add logging to Retrofit, we would have to change the code for every Retrofit instance created. We can say that it is another application of Separation of Concerns. We seperate the code that instantiate objects from the functioning code. DI is important part of the Android architecture. With DI we can do the plumbing between layers, also have control over the resources used.

What architectures solve on Android?

Unit Testing

One of the biggest reasons we use an architecture pattern and DI is have a unit testable project. Unit testing is done by isolating the unit you want to test (class, function etc.) and controlling all the inputs and outputs. The way to control input and output is to control the dependencies. Instead of the real resources, mocked objects are used to provide inputs and verify outputs. With DI we can provide real objects when we application is running or we can provide mocked objects when we are running unit tests.

On Android we extend Activity, Service, Fragment etc. Classes to interact with Android system. But it makes unit testing harder because we can use the members inherited from the parent classes (usually from Context) and since we have not provided inherited elements we don’t have control over them. To avoid this issue, we try to put code as little code as possible to classes extended from Android(or any other library) for easier unit testing. I also want to note that using singleton pattern makes mocking harder. Even though Mockito cannot mock static(in Kotlin case companion object), frameworks like Mockk and Power Mock can. But with the DI we can avoid it all together.

As you can see we can isolate the testable code into layers with architecture patterns and control the resources with DI.

Activity Lifecycle Problems

In the previous post I mentioned about Activity lifecycle problems. When the configuration is changed (mostly caused by screen rotation) the Activity is destroyed and a new one is created. If a long running operation like an API call running on a different thread while the configuration is changed, callback to the main thread that would notify user about the result of the task, cannot find the first Activity. If not handled correctly it could cause crashes. Also, we can lose the result of the task. We can retry the operation again to get the result but it is a one-time thing like a money transfer, we cannot do that. With an architecture pattern we have layers that won’t be affected by the Activity or Fragment lifecycle and notify user by whichever View layer is available. Also keeping the state information and data in the Logic layer prevents losing them when the Activity is recreated. DI frameworks make it easier to do connections between layers after Activity is replaced. By using Architecture patterns and DI we won’t be affected by the lifecycle problems.

There are also several other advantages especially on the code maintenance but I have tried to explain Android specific ones. There are other Architecture patterns and DI frameworks I haven’t mentioned. Feel free to investigate the ones I mentioned and the others. Also keep in mind that learning them would be tricky and don’t be overwhelmed by it. Try to understand why they are used and what they do. In the next post I will talk about Android Architecture Components. See you on the next one.

Here is the final part of the series:

📝 Read this story later in Journal.

👩‍💻 Wake up every Sunday morning to the week’s most noteworthy stories in Tech waiting in your inbox. Read the Noteworthy in Tech newsletter.

--

--

Hadi Tok

Google Developers Expert for Android | Software Engineer @Facebook | ⋰Ẍ⋱Circassian⋰Ẍ⋱