Update November 2018

Please have a look at my newest library !!

Welcome to Part II of this series, in this article I’m going to show with real code examples how i structure an application and the flow of an action(I use the word “action” to represent something like “show a list of users”, “login”, etc..).

The code in this article was written some months ago and some libraries have been updated since them, Retrofit is one of those cases, i’m using version 1.4, a new version 2.0 is already out there and some things changed in the API. Some modifications were made to adapt the code to this article and i haven´t tested it, however everything should work with little or no changes.

Practical Use Case

Imagine a very common use case like getting a list of “something” from a remote server, in these case i’m going to fetch a list of events, an event can be a music concert or a discount happening at some bar.

Step by step:

The user opens an activity

The request is made to fetch the list of events

The UI is updated with the events

We could save the events in a DB to load them from disk the next time, however we are skipping that part. In my opinion it is a good practice to always load the data from cache, DB, memory first and then update the content from the network. This way the user always sees content while the app is fetching new data and gives a fluid feeling to the user.

Now with some code(ignore de @inject @bind annotations if you never used Dagger or ButterKnife before, i’ll explain it later).

View

EventsListActivity

EventsListFragment

Good Practice

It’s a good practice in the community to create a static factory method in Fragments, Android OS needs the fragment constructor to empty, using a static factory method we can do some initialization before returning the fragment. It’s basically a simple level of abstraction.

Let’s talk about the fragment

This is a simple fragment, with a recycler view to show the events, we inject the views with ButterKnife and the dependencies with Dagger 2. The most important part is the getEvents() method, as you can see we only talk with the controller to make the request, after that, when the request is done the onEventMainThread will be called receiving the GetEventsFinishedEvent containing the list of events.

As you can see, the fragment(view) is completely separated from the domain logic, it only knows that it will receive a list of events but doesn’t know from where, maybe it’s a network request, maybe from a DB, memory, etc.

The fragment’s job, is to handle the interaction with the user and ask the views to draw it’s content.

Controller

MainController

A controller is a simple interface, in this case i have done an implementation that uses JobQueue library from Path to do background work, the only responsibility of the controller is to create the job and add it to job manager.

By abstracting the controller with an interface, we can swap the controller later, we will see it in the part III of this series. Imagine that we don’t want to use JobQueue library anymore, and now we want to use Android Services to process the request, we can do it fairly easy.

Model

GetEventsJob

The model is represents by a Job, a Job is a component from the JobQueue library that will run in the background, the main point here is that we encapsulated the getEvents request and we can know test it separately and use it anywhere we want it in the app. The data binding as you can see is made through events, we post an event to the event bus and anyone interested will receive this event, this de-couples every component in our app because the job has no idea who will receive the event.

GetEventsFinishedEvent

The event fired when the request is done, this is a plain java object that stores a state, to know if the request is successful or not, and the list of events fetched from the network.

This is a simple use case but it’s enough to represent how the code is structured, we can actually define a series of steps that are made when a new feature is added. Imagine we want to add a login to our app.

Add a new method to the controller called “void login(String pass, String username)”

Add a new job that encapsulates the logic for that feature, LoginJob

Add a new method to the API declaration, login(…)

Create a new bus event that represents the feature for example, LoginEvent

Register a subscriber in the view to receive the LoginEvent and call the controller method “login(…)” in the view

That’s it, normally every other use case will fit in these steps, register, like an event, get event details, whatever, it’s always the same steps. It keeps our code organized, modular, testable and easy modify later if we want.

MVC on Android — Dependency Injection with Dagger 2

In the above examples i used Dagger to inject dependencies in the code, for those not familiar do Dagger or dependency injection i’ll show a very quick tutorial on how to configure Dagger 2 in Android. I’m new to DI as well, so this is not a deep guide on Dagger but instead a brief tutorial on the advantages of DI and Dagger.

For a beginner, Dagger 2 may seem a bit difficult to grasp at first, so hopefully you will get an idea how to start using it.

Dependency Injection

Normally you’re used to create the objects you need, in DI the opposite happens, there’s an inversion of control, and know you ask someone or something to create the objects and return them for you.

In my experience DI is specially helpful to test code and, you can easily inject mock or stub objects.

Ex:

public void someMethod(){ Api api = Factory.getApi(); }

In this ex, if you need to get a mocked version of API to unit test this code it’s very difficult, by using DI you basically say, “Give me an API object”, it’s not my responsibility to create one.

@Inject Api api; public void someMethod(){ api.getEvents(); }

Dagger 2 is a very powerful DI library, that performs really fast making it ideally to use with Android applications. I’ll show the normal configuration i use when working with Android. In dagger there are two main elements, components and modules.

Components , component is a interface where you declare the injectable classes through a series of “inject(…)” methods, it’s the glue between the modules and the injectable objects.

, component is a interface where you declare the injectable classes through a series of “inject(…)” methods, it’s the glue between the modules and the injectable objects. Modules provide all the dependencies that your objects need through a series of “provideXXX” methods, this is where you configure and create the objects to be injected later.

I use only one component for the entire application, separating the dependencies in several modules.

In the above example i created a component that will inject EventsListFragment and GetEventsJob, annotated with the @Singleton to make sure only one exists. After creating the component you need to specify the list of modules that provide the objects we need to inject, in this case using the @Modules annotation and specifying a list of modules.

Android Module

A modules is a class that you annotate with @Module, after that you create a series of methods that must begin with “provide” and return the object you want.

JobManager Module

EventBus Module

I like to create various modules, separating the dependencies, but this is just a personal taste, i think it’s makes it easier to mock a specific dependencies, for example, if i want a mocked JobManager i can swap the JobManager module to a MockedJobManager and return a mocked object instead, we will see how to do it in Part III.

Initialize Dagger

At some point, after we have defined our modules and components we need to initialize Dagger.

We extend Application class from Android SDK to initialize Dagger during OnCreate method. Dagger will automatically create a Builder for each component you define with the name Dagger{ComponentName}, in this case DaggerApplicationComponent, using the builder we can set the modules needed by the component.

If the module has an empty constructor we don’t need to create manually, Dagger will do it for us, otherwise we need to create it manually like the Android Module in the above example.

Helper class to init dagger.

Application class

@Override public void onCreate(){ initInjector(); } private void initInjector(){ DI.buildWithProdModules(this); }

As you can see it’s a very simple class that only creates the component and has a pair of getter/setter methods. We can use it like this to inject our objects everywhere in our app.

DI.get().inject(instance)

MVC on Android — The Navigator pattern

The navigator pattern is something that i use to navigate between screens in Android, its a simple object that encapsulates the logic to navigate to an activity, to go back form that activity. This is useful to create consistent animations and to centralize all the logic avoiding startActivity(), finish() and overridePendingTransaction() calls throughout the app. This code could probably be wrote in a better way but it serves the needs for my use case, we could probably tailor it to your case if you want.

This ends the part II of this series and it was a long part II, on part III we will see how we can test Android applications using Espresso, and how we can unit test code using Dagger to inject mocked dependencies.

Other libraries you may find useful

Sérgio Serra

Mobile Developer

sergioserra99@gmail.com