Android Application Architecture - Guide For Developers

Developing quality Android applications is hard and complex. The code we write has to be testable, robust and flexible enough to adapt to growth and changes. Android framework does not enforce us to write code in any specific architecture, which can be a good or a bad thing depends on our decisions.

How to develop a good Android application?

Couple years ago almost nobody cared about how to develop a good Android application. Nowadays, on the other hand, we have a lot of examples how to use MVP, Clean Architecture, VIPER but why should we care? Well, there are many important things we should be aware of.

Choosing the right application architecture can make dealing with all these challenges much easier but before we’ll dive into it, we should take care of some basics which will make our life much easier.

Basics of Android app architecture

Package structure

Instead of using layer structure like fragments, activities, adapters etc. you should package by feature. Grouping classes by feature provide higher level of abstraction, more readable and maintainable structure, easier code navigation and it’s much easier to scale.

For example, if you have DetailsActivity, DetailsFragment, DetailsListAdapter, DetailsItemModel you should put them in one package.

If you have a custom Application class make sure to put in in the top-level package.

File naming

Class files

Any class name should be created using UpperCamelCase, for example, ListActivity, DateHelper etc.

When a class extends an Android framework component it should always end with the component name, for example, ListActivty, ListFragment, ListAdapter etc.

Layour files

In the case of XML files names, you should always use lowercase letters and underscores, for example, activitybook, fragmentbook, item_book. It makes it clear as to what the layout is used for. Every layout file should be named starting with the name of Android component that it has been created for:

Drawable files

Drawable resources should be named using the corresponding prefix to make it clear to what exactly the item is used for. It will also help to group similar items.
Most common drawable types should use the following prefixes:

To create selector state resources you should use the following suffixes:

Code style

The most important thing to remember about code style is the fact it should be shared across the developers who work together. Code style config file can be easily exported from Android Studio and used by other developers.

Android Studio

Strictmode

Android has a tool to catch many common platform-specific problems that bridge the gap between compilation errors and runtime crashes. StrictMode analyzes your application at the thread or virtual machine level and alerts you with potential problems.

To use strict mode all you have to do is some configuration in your custom application class. See the following example:

The above code enables all the checks, make sure to check StrictMode | Android Developers to understand what all the possible checks means and choose the most important ones for your application.

Android Application Architecture Guide For Developers 3 UlamLabs

As you can see, MVP divides the application into three types of components:

Short summary how you should use the MVP on Android:

Now we already know what MVP is and it’s time to use it in our Android application. Let us assume we have to implement a screen which will display a list of some repository contributions.

View

In a real world example our view should be able to:

Based on this list we can create the view interface:

Basically, it doesn’t matter what will be implementing this interface and it totally depends on how you want to create this screen. It could be an Activity, a Fragment or a custom ViewGroup. We are going to use an Activity:

Model

Our model layer will contain couple classes.

A simple POJO to map an API response:

Github API interface (using Retrofit, if you don’t know what is it make sure to check Retrofit):

Presenter

The presenter is responsible for calling a GithubApi, and passing the results to the view.

This is what is going on step by step:

Testing Android application

We’ve implemented our screen and it’s time to check if it works properly. To ensure everything works like its supposed to we are going to create two tests:

Unit tests

To test our presenter we need to mock its dependencies. To check the interactions we have to provide mocked version of AppRepository class. To mock dependencies, we are going to use Mockito.

What unit test should actually test? In our example, we want to check if a presenter calls the right methods on a view.

That way you can test every case which should be handled by your presenter.

There is also one important thing to handle. To avoid flaky we should make our asynchronous operations synchronous. To accomplish it we created a class called ThreadConfiguration and we provide it as one of the dependencies.

Asynchronous operations in our case are performed in RemoteRepository class and this is where we use ThreadConfiguration class in conjunction with RxJava compose operator.

In the application, we use a separate thread for network operations and we observe the results on Android UI Thread.

In the unit tests, on the other hand, we make everything synchronous by supplying the same thread for performing network operations and observing the results.

UI tests / Functional tests

To ensure users won’t get a poor experience when using our application we are going to write couple UI tests. On Android, the easiest way to do it is to use Espresso . Espresso is an official framework which provides a lot of useful API’s to simulate user interactions. To make sure our tests are stable we have to cover two topics.

In most cases we use RESTMock library which is built on top of OkHttp mock server and provides a way to verify the HTTP requests which our application sends ( GitHub – andrzejchm/RESTMock: HTTP Server for Android Instrumentation tests)

With basics covered we can start configuring our tests. UI tests are run by AndroidJUnitRunner. To start a mock HTTP server and register a custom idling resources we have to create a custom runner.

All we have to do now is to register our custom test runner as default one. To do this we have to specify set is in build.gradle:

With all the basics covered we can start writing tests! You can check some simple tests which cover couple cases in our sample repository https://github.com/ulamlabs/android-starter/blob/master/app/src/androidTest/java/com/starter/ui/contributors/ContributorsActivityTest.java

Summary for Android application architecture

This blog post doesn’t cover all the details about each section and it was intended to show briefly how you can write Android applications which will be easy to scale and test. Stay tuned to more detailed posts about each section and make sure to check our sample repository in the meantime!