Building native Android apps is fairly simple: just throw some Java code together, add some XML to it and there you have it: a cool new Android app. But also sadly in most cases an unmaintainable Android app in the long run.

For many developers this seems to be just fine but I often asked myself why the code I wrote got more and more messy with every feature I added. I refactored a lot of the code step by step but it still felt very ugly.

A global application object held the database connection and was referenced everywhere and references to Android activities where being handed off between each other e.g. to refresh data in lists. What I was missing was dependency injection and a clear system for events occuring in my application.

The sad thing is that the otherwise very good Android SDK has no such concepts in it. Nontheless after some research, I found these two little but very helpful libraries:

dagger for dependency injection

otto event bus system

Inject ALL the dependencies!

Installation of both libraries is fairly easy through Maven or just download the Jar files of the current versions and put them in your project’s lib folder.

I started to refactor the handling of the database connection, because I use it in many places throughout my application. Handler classes that run SQL on the database and return ArrayList<?> are used in activities to retrieve data from SQLite and save newly created data.

With the use of dagger, my handler looks like this now:

public class FoobarHandler { @Inject Database database; public ArrayList getFoobars() { return database.getWritableDatabase().query(...); } }

The @Inject annotation is defined in dagger and it will build a dependency graph on compile time on your dependencies and automatically inject the correct object based on it’s type. A special constructor or method to set the property is no required.

Several other options are available and you can read about it in full length in the dagger documentation.

Events are everywhere

In every mobile app, several different types of events occur when it is used. There are events when data has been changed, when the user creates new data or when data is loaded from a remote server to name only a few.

And often your application needs to act on those events, e.g. by refreshing a list or showing an error message when the device is offline and can’t load data from a remote machine.

Otto is based on Guava and very easy to use which makes it a perfect candidate to build a sane event-based architecture for Android apps.

It can be injected via dagger into every activity that needs to dispatch and subscribe events. Below is a simplified example that fetches translations from a server:

import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; public class MainActivity extends Activity { @Inject Bus eventBus; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); eventBus.register(this); } public void fetchTranslations() { ArrayList translations = new ArrayList(); // fetch 'em from remote ... eventBus.post(new TranslationsFetchedEvent(translations)); } @Subscribe public void onTranslationsFetched(TranslationsFetchedEvent event) { ArrayList translations = event.getTranslations(); // do something with the data of the event here ... } }

As you can see in onCreate , every possible subscriber needs to be registered to the bus in order to retrieve events. To dispatch events, just use the post method on the bus and give it an event object (POJO). The subscriber methods need to have the @Subscribe annotation and the parameter is the event object, which is also the „channel“ on which it will listen. The name of the method is arbitrary, though.

Also, the event object is just a Plain Old Java Object but you should take care of it’s name as it should clearly say when this event is being posted.

Now, start your engines!

Now that you know how I learned to build maintainable apps, I hope you can take anything from my journey into yours and I am very eager to hear of your favorite libraries to build sane and maintainble Android apps in Java.