Taking Command of Android Development

Throughout my Android career, I’ve often been asked to complete what sounds like a simple task:

Get information from a server to a UI.

While this is the most common task we do as mobile devs, Android has not made it easy. Challenges presented by the framework include:

  1. Inability to perform IO (network & disk) operations on main thread
  2. Poor exception handling in built-in threading components (I’m looking at you AsyncTask!)
  3. Clunky instance state management
  4. Boilerplate galore

Working with and displaying network data doesn’t need to be difficult

Luckily for us, as the Android ecosystem has grown and matured, open source solutions that can mitigate all of these problems have started to emerge. This article will introduce you to a few of these libraries and tell you how they’ve changed Android development for me. While I won’t be providing a detailed explanation of how each library works, I will include resources that helped me learn each of them. My hope is to introduce you to a set of tools that I can’t imagine starting a data-driven project without.

Libraries I’ve grown addicted to

  • Retrofit (Networking)
  • Dagger (Dependency Injection)
  • RxJava (Threading, Functional Programming)
  • Butterknife (View Injection)
  • IcePick (View State Persistence)

Patterns that have served me well

Singleton — Both Application-wide and scoped to something like an Activity

Command — Encapsulating a request as an Object

Observer — Encapsulating a Response as an Observable

Summary of Libraries

Retrofit

Retrofit turns your REST API into a Java interface. http://square.github.io/retrofit/
Retrofit has been able to fulfill every networking demand that I’ve thrown at it. It’s a breeze to add headers, use your own JSON marshaller (GSON is built in), or even pass in your own network client. RxJava support was recently added as well (can return Observables instead of scalar values). Check out how little you need to get started:

Resources:

RxJava

The next piece of the puzzle is RxJava, which solves issues with threading and exception handling and is fun and concise to boot. RxJava implements the Observer pattern and builds a set of functions on top of emitted values.

RxJava also makes it easy to work with I/O in a non blocking manner. Instead of calling a method and waiting for a result (while blocking your thread), you subscribe to an Observable and instead get passed the result when it is available.

Additionally, RxJava adds schedulers which dramatically reduce the complexity of parallel tasks. With two lines of code you can tell your observable which thread you want to run the observable on and which thread you want the items to be emitted to. Since you are doing work on a background thread, you can subscribe to many observables in parallel rather than in serial.

Let’s say we want to fetch data using retrofit in an Activity from the following endpoint.

@GET(“/search/users”) Observable<UserResponse> users(@Query(“q”) String name)

From an activity, we can call:

A couple are things are happening here:

  1. We ask retrofit for data
  2. We tell it to give us that data on the main thread
  3. We tell it to do the work on an IO thread (which RxJava manages for us)
  4. Finally, we subscribe to the Observable and pass in which methods to call on success and on error.

No additional threading is necessary. We will subscribe to our endpoint and the result will be sent to us asynchronously whenever it’s ready. Note: I am using RetroLambda which adds Java 8 lambda support to Android (much cleaner syntax when working with RxJava). Observables can easily pass exceptions as well, even across threads.

Resources

Dagger

The best classes in any application are the ones that do stuff: the BarcodeDecoder, the KoopaPhysicsEngine, and theAudioStreamer. These classes have dependencies; perhaps a BarcodeCameraFinder, DefaultPhysicsEngine, and anHttpStreamer.
To contrast, the worst classes in any application are the ones that take up space without doing much at all: theBarcodeDecoderFactory, the CameraServiceLoader, and the MutableContextWrapper. These classes are the clumsy duct tape that wires the interesting stuff together.
Dagger is a replacement for these FactoryFactory classes. It allows you to focus on the interesting classes. Declare dependencies, specify how to satisfy them, and ship your app. — http://square.github.io/dagger/

Dependency injection has always been a key tool in the Java developer’s toolbox. One of the most popular Java libraries (Spring) built its popularity on the concept of externalizing the creation of dependencies from class implementation. Dagger has taken this concept further by making dependency resolution a compile-time task (rather than runtime task) using a concept called Annotation Processing.

In Dagger, you create modules which define:

  1. What is scoped to the module with providers for things that cannot be auto injected
  2. What objects act as a starting point to an injection chain (Activities, Views, Tests, etc)

Next, we’d need to make an application scoped object graph containing the modules that can provide “Global” singletons. Ideally, we would also create subgraphs, such as an activity graph using modules that contain objects that can provide Activity scoped singletons. Subgraphs inherit everything from a parent graph, giving us control over when we will create or destroy a subgraph.

Sample implementation: I can have an activity graph that inherits from an android graph. We create and destroy the activity graph every time we start a new activity. This creates and destroys delegate objects like ActionBarHelpers and AlertHelpers. Anything in the android graph, however, will live past the Activity lifecycle. Ideally, you will keep data providers scoped to an android graph so you don’t need to create and destroy them each time you create or destroy an activity.

After everything is wired together, you can inject dependencies directly into your objects without having to instantiate them.

@Inject Github api;

Dagger reduces the amount of boilerplate within classes. Now, the only code in most classes is the actual implementation (not wiring/instantiation details).

Resources

Butterknife

While it has a wide range of functionality, I primarily use Butterknife for view injections:

@InjectView(R.id.suggestionBox) SuggestionsBox suggestionsBox;

Viola, type safe view bindings!

IcePick

Icepick is an Android library that eliminates the boilerplate of saving and restoring instance state. It uses annotation processing to generate code that does bundle manipulation and key generation, so that you don’t have to write it yourself.

Icepick helps save instance variables that are declared in an activity and restores their state on rotation. It’s simple and effective.

Example usage in a custom view:

@Icicle int index;
@Override public Parcelable onSaveInstanceState() { return Icepick.saveInstanceState(this, super.onSaveInstanceState()); }
@Override public void onRestoreInstanceState(Parcelable state) { super.onRestoreInstanceState(Icepick.restoreInstanceState(this, state)); }

RxCommander Pattern

A Commander is a concept that helped me bring everything together (see sample project at end of article for implementation). Think of a Commander as an encapsulation for a particular network endpoint. You need to tell a Commander:

  1. ObjectType for Request
  2. ObjectType for Response
  3. What to call to load a fresh response

Commander supercharges your request by :

  1. Adding rxJava support to any network client
  2. Cacheing network responses in memory
  3. Piggybacking on in-flight requests.
  4. Loading cached or network data (or both!)

A client interfaces with a Commander through the following commands:

Observable<V> fresh(final T request)//new network hit
Observable<V> all(final T request) //first cached if available then fresh
Observable<V> cached(final T request) //cached response only
Observable<V> get(final T request) //if cache exists return it, otherwise return a fresh response

Below, the user commander will emit a cached response if it exists. Otherwise, it will make a network call and emit the network response.

With Commanders, rotation is a non-issue. If I call .get() after a rotation, I’ll just get the cached response. As we are dealing with observables, you can transform, combine, and filter your observables data as you see fit.

Ideally, Commanders would be application scoped singletons that multiple activities can subscribe to and share data with, but that’s definitely not a requirement for use. Additionally, you can subscribe to a Commander and be emitted any response that the commander emits (not just for a particular request but for any request).

Testing is a breeze because you can inject your Commander into your tests, call one of the commands, and do a toBlocking().first() to make the result synchronous.

Full working example utilizing the pattern and libraries above.

My typical workflow

Create new retrofit method interface for new endpoint

Create RxCommander for endpoint

Register new Commander with AndroidModule

Create an Activity/Custom View

Inject the Commander into an Activity or View

Call one of the four commands on the Commander.

The Commander Pattern works for me and I hope it will work for you too.
Show your support

Clapping shows how much you appreciated Mike Nakhimovich’s story.