Async Android

RxJava is increasingly popular in the Android developer community. I was thinking back to the “ah ha!” moment when it’s usefulness really struck me. Even before getting to grips with RxJava’s functional aspects, it looked like a neat alternative to AsyncTask and Loader.

I’m going to explore Android’s threading abstractions and explain why RxJava can provide a more satisfying API for expressing asynchronous operations.

In the beginning

Let’s go right back to basics. All Android apps start with a single thread: the main thread (A.K.A “UI thread”). This is the thread we must use to make View updates, and it’s where we receive framework callbacks like onCreate().

Let the main thread do it’s thing

Executing long-running operations on the main thread is bad for performance and bad for users. It means dropped frames, janky animations and unresponsive interfaces. In the very worst cases, the system will show the user an ANR (Application Not Responding) dialog and ask if it should kill the app.


We want to keep the main thread free to make UI updates as close to 60FPS as possible. This means that any slow or blocking operations like network access, database queries or intensive computations must be performed on background threads. The good news is that we’ve got options.


Creating a new thread is straightforward. Thread is the building block for every approach, but it’s not going to provide a great developer experience on it’s own.

It’s often necessary to react to the result of a background operation on the main thread. A result can be sent to the main thread with a Handler. In the example, Activity.runOnUiThread() simply posts to a main thread Handler internally. Either way, it’s not particularly elegant code.


Creating a new thread for every single background operation isn’t ideal behaviour either. One option is to create a custom abstraction, perhaps sending a Runnable to a thread pool, but there are several more general-purpose tools available.


IntentService is perfect for firing off background tasks when it’s not necessary to react to a result on the main thread directly.

It must be declared in the AndroidManifest.xml just like any other Service. Then it can then be started by sending an Intent (that can include any parameters).

startService(new Intent(this, BackgroundService.class));

An IntentService has it’s own worker thread. It operates serially, queuing subsequent invocations. It’s completely decoupled from the app UI, so there are none of the complexities that arise from an Activity being recreated (e.g. due to a configuration change) when a background operation is in progress.

On the other hand, this approach is not particularly well suited when a main thread update is required. It is possible to post a result to an event bus and listen from the UI, but that can become unwieldy as a general solution.


Painless threading? Well, AsyncTask does have some shortcomings, but it’s the first of several abstractions with a clean separation between the code that runs in the background and the code that handles the result on the main thread.

The interface provides two important callbacks:

  • doInBackground() is executed on a worker thread
  • onPostExecute() receives the result on the main thread

It’s also possible to override onProgressUpdate() and receive progress events on the main thread.

AsyncTask works just fine in simple cases. So what’s the problem? We already touched on handling configuration changes, but that’s a common challenge for threading abstractions that live in the context of an Activity. There are three more concrete limitations.

Error handling

Operations that need to be executed on background threads tend to have a lot of failure cases – especially I/O. Network requests fail. Common patterns involve returning exceptions in result objects or storing them as state in the task. This means that we always need to check for error results (or null) and might end up dealing with less meaningful types.

Callback hell

Chaining multiple asynchronous operations together is complex and error-prone. Scenarios where multiple individual tasks depend on each other are not uncommon, though.

callbackhellChained or nested callbacks lead to “callback hell”. It becomes difficult to reason about the flow of control, and the possible failure of the whole chain must be handled in each callback.

Execution order


This is just a piece of history, assuming a minimum API level 14+. The default threading behaviour of AsyncTask changed twice between platform versions. This resulted in some subtle bugs, inconsistencies and confused developers. It can be specified manually with executeOnExecutor().


Loader is an evolution of AsyncTask in many ways, and it shares some of the same limitations.

The key difference is that a Loader binds to a host Activity or Fragment. It allows background operations to continue and be restored relatively seamlessly across configuration changes. This is great. It solves a common and surprisingly difficult problem. However, being tightly bound to the framework often provides a separate set of challenges for unit testing.

There are cases where this might be the right tool for the job. For example, CursorLoader does quite a lot for free in combination with ContentProvider. I used it when I was building Sudoku, and it worked well, but that’s a relatively simple application.

In an ideal world

Thread, IntentService, AsyncTask and Loader all provide mechanisms for running code in background threads. They have some distinct characteristics and some shared limitations. So what would an ideal, general-purpose solution for expressing asynchronous operations on Android look like?

  • Main thread callbacks
  • Persistence across configuration changes
  • First class error handling
  • Composability (a solution to callback hell)
  • Simple, explicit control over threading behaviour


RxJava is a library for the Observable abstraction and related higher-order functions. It allows us to meet 4/5 of the criteria above with little effort and it supports the functional-reactive programming paradigm in Java.

At this point, it’s fairly well battle-tested on Android. It’s been in production in the SoundCloud app for over two years and it’s used by several other companies like Trello, Square and The New York Times.


An Observable emits items. Any operation can be represented as a stream that:

  1. emits 0 or more items
  2. either completes or terminates with an error

Marble diagrams help to visualise the output of a stream over time.



A Subscriber consumes the output of an Observable. Subscribing to an Observable is essentially registering to receive items emitted from that stream.

  • onNext() receives items emitted by the Obserbable
  • onError() is a terminal event that receives a Throwable
  • onCompleted() indicates that the stream completed successfully

In addition to a separation of concerns between background and main thread work, there is a clean split between logic for handling success and failure cases.


Two important operators define the threading behaviour. In this example, the Observable should execute on a background thread, so it’s assigned to the I/O thread pool with subscribeOn(). The Subscriber callbacks update the UI, so they need to run on the main thread. This is defined with observeOn() and the Android main thread scheduler.

Composing streams

What about “callback hell”? This is where the real power of functional-reactive programming comes into play. RxJava provides an extensive set of operators for functional composition and transformation of streams. Multiple asynchronous operations can be combined with operators like flatMap().


In general, these operators allow us to write more expressive, less stateful code. Many are familiar if you have exposure to functional programming.

Problem solved?

Kinda! We’ve seen how the Observable abstraction incorporates error handling, composability and scheduling (including the Android main thread scheduler).


However, the emoji-based feature comparison shows that RxJava (RxAndroid really) doesn’t provide an out-of-the-box solution for the configuration change problem. Operators like cache() and replay() can play a part, but the strategy for retaining a reference to an Observable will depend on individual architectures.

Some problems solved, some new problems

I want to share a few of the downsides and challenges, because nothing is perfect. These are the topics that seem to come up most often in conversation.

There is a learning curve. Incorporating a new programming paradigm requires you to think about problems in different ways. It can take some time to get familiar with the many useful (or sometimes just very complex) operators.

groupjoinThere is no “correct” way to use RxJava. It can solve a few different problems, so it’s worth reflecting on how it fits into your own architecture and problem-set. A threading abstraction? A tool for representing logic in streams? An event bus? UI bindings?

At some point, you may encounter a very Rx-specific issue called “backpressure”. This occurs when a stream is emitting more items than the subscriber can process. It’s necessary to be mindful of this constraint when using the main thread scheduler, since there is some thread switching overhead.

Currently, Android has no official support for lambda expressions, so function definitions involve a lot of boilerplate. The Retrolambda project backports Java 8 lambdas with Android support.


The default abstractions for expressing asynchronous operations on Android have several limitations in complex scenarios. RxJava provides a full-featured alternative with all the additional power of functional-reactive programming and a simple interface for handling results and errors. Replacing an old AsyncTask is an easy way to get started.

  • StrictMode: an essential tool for identifying long-running operations on the main thread
  • @UiThread / @WorkerThread: support annotations for static analysis of threading bugs

Thinking in streams

RxJava demands a bit of a mental shift if you’re used to imperative programming. Choosing the right combination of operators to express complex logic as a stream only comes with time and experience.

Recently, I ran into an old problem that I’d solved with unnecessarily verbose and stateful code. I want to share the original and revised versions, because the solution is incredibly succinct once RxJava is used to it’s full potential.


Assume the following Observable makes an HTTP call and emits a single result: Observable<ServiceResult> fetchResult(). The ServiceResult may indicate that the output we’re really interested in is still processing, so:

  • Poll every 2 seconds
  • Return the first time serviceResult.isProcessing() is false
  • Try a maximum of 3 times

First attempt

It sounds like the requirements can be met with a simple while loop. This is possible with Statement.doWhile() from the RxJava Computation Expressions package, but it requires keeping track of polling state and providing a function for the loop condition.

The state can be updated each try in doOnNext(). The delay between requests is simple to achieve with Observable.timer() and a filter() function prevents the pending results from being returned.

Streams over loops

The revised solution is equivalent, but it’s no longer necessary to manage any polling state.

  1. Start with a stream that emits on a 2 second interval
  2. Limit the stream to 3 values
  3. Each tick, fetch a result
  4. Take the first value that’s ready

The stopping condition that was previously implemented with the shouldContinue() function is now part of the call chain definition in 2 and 4.

 Pro tip

Observable.timer() and Observable.interval() have versions which accept a scheduler parameter. This is extremely useful for unit tests, since it allows assertions to be made about the values and events emitted as time is advanced with TestScheduler.

SSL proxying with Charles

Charles is a great development tool for inspecting HTTP traffic. Here are the steps to enable SSL proxying with a Genymotion Android emulator and Charles 3.10:

  1. Proxy the emulator traffic to the host machine
    1. Long press “WiredSSID” and choose to modify the network
    2. Create a manual proxy with host and port 8888
  2. Enable SSL proxying in Charles
    1. Proxy > SSL Proxying Settings… > Enable SSL Proxying
    2. Add hosts for the traffic you want to inspect
  3. Install the Charles certificate on the emulator
    1. Go to in the emulator browser
    2. Name the certificate and select Wi-Fi credential use

A PIN lockscreen is required to install the certificate in 3.1. Note that is a Genymotion-specific IP for the host machine. Setting up a physical device is similar. Just make sure the machine running Charles is on the same network and use it’s IP address in 1.2.

TV Critic

There are large-format displays dotted all around the SoundCloud offices. They’re used for everything from API graphs to news about who’s visiting from out of town. Teams customise the content of nearby displays. We have a few pages rotating in the Android corner:

  • CI build status
  • Mobile API graphs
  • Google Play reviews

I created the app review dashboard to bring our team closer to our users. TV Critic is a tiny web app that pulls the latest reviews from the app stores and formats them as HTML for the big screen. It supports Google Play and Apple App Store.

TV Critic pointing at android/com.jdamcd.sudoku

The display is an information radiator for user sentiment – clearly highlighting ratings. The reaction has been extremely positive. It’s a motivation boost when the board lights up green, and it provides useful clues when things aren’t going so well. Most importantly, it spreads empathy for our app users and reminds us why we’re building the product.

android-crop 1.0.0

Last week I published version 1.0.0 of android-crop – a simple image cropping library for Android.

This library began as a replacement for a fork of an unmaintained project that we were using at SoundCloud. It hadn’t been getting much love, and most importantly for me, the UI looked really dated.

Image cropping is not a major feature in our app, but it’s a useful part of the recording and sign-up flows. Leaning on a library for this functionality keeps our project focused.

The library aims to provide:

  • Gradle build
  • Modern UI
  • Simple builder interface for crop Intent
  • Example project

The following snippet starts a crop, loading the image in the library UI and saving the cropped version to the specified URI. This example also includes an aspect ratio option, which specifies that the output should be square.

Crop.of(inputUri, outputUri)


The image cropping logic itself comes from the AOSP camera code and is largely unchanged. Find the full source and documentation on GitHub.

Sudoku icon refresh

Modern robots float, right?

Sudoku was recently updated with a fresh new material design. The app icon stood the test of time. It dated back to 2010 when I was building Android apps in my bedroom at University. But a lot has changed since Android Froyo. It was time for something clean, modern and material.


Guenther Beyer of Opoloo designed the original icon. We talked over some ideas for an update and agreed that it was important to maintain it’s personality. People seemed to relate to the robot character. It stood out, and that’s critical in a highly saturated category like sudoku.


My favourite detail of the new version is the paper fold. Paper is the basis of Google’s material design language, but it also relates to the motivation behind the game – it should feel as simple as pencil & paper.


The importance of a great icon shouldn’t be underestimated. Sometimes it’s your one shot to make an impression, and begin to tell a story about what makes your app different from the rest.


Download Sudoku on Google Play

Android Engineering for Scale

Presented at Droidcon London 2014 (with Guillaume Lung) and Droidcon NYC 2015.

When I joined SoundCloud our mobile team was small, but it would soon transform significantly to face challenges of scale in terms of team size, ever growing codebase and number of users.

Some things needed to evolve: the app architecture, branching strategy, code review policy, team structure and release process.

Other values supported us: unit & acceptance testing, pairing, continuous integration, end-to-end development, user empathy and reactive programming.

This talk covers both the processes that are working well and the ones we’re striving to get right.

Sudoku 1.3

This update brings Google Play Games integration and a series of UI improvements.

Download Sudoku on Google Play


Google Play Games

  • Collect achievements
  • Compete in leaderboards
  • Never lose completed games with cloud save


  • Completely redesigned scoreboard
  • Hide completed puzzles from lists
  • Improved tablet layouts


  • Disable solved digits (optional)
  • Clear all notes

The sudoku solver has been unbundled. It continues to be available as a separate app on Google Play.

Download Sudoku Solver