Making your Android app reactive

| 2 Comments | 7 minutes read

I recently had the opportunity to rewrite one customer’s Android app. The solution were stuck up with components coupling, complicated thread synchronization and problematic callbacks system. The components were not testable, constraint to random coordination of used sub systems (bluetooth, network calls…). The best way to get back to a healthy solution was to recover its inner core business and extract from confusing technical code.

Let’s take a simple example, to illustrate how to write a reactive application. This article shows a way of rewriting a reactive Android API with RxJava/RxAndroid. It could be easily applied to any project that handle multiple flux of data. You will find references to other blogs, that helped me understand this kind of approach. Let’s go with the reactive weather app (sources available on github).

The weather app

The weather app is a simple app that asks for a location (red fab button) and gives back the weather for this location:

weather-app

Sun for Paris !

This app uses a SDK, which is in charge of downloading GPS coordinates of the location and the weather (WeatherSDK.java). Below the geocoding method (the other service of the SDK; getWeather, is quiet similar):

SDK_without_Rx

SDK method with callback on main Android thread

The callback is a simple interface to help handle response and error:

SDK_callback

Under the hood, we use retrofit (1.9) to make our network calls. MainModule.java setup retrofit and WeatherWS.java defines the services to call:

retrofit1_build

retrofit_norx

In the weather app side, displaying the weather is quiet complex with cascading callbacks (MainActivity.java):

App_without_Rx

The SDK has to handle the response in a background thread and give the hand back into the Android main thread. The thing is quiet tricky for remote API calls. Client integration can be quiet complex too (response handling, difficult reuse, errors catching…). Imagine it with complex business and subsystems call 😉

Making things observables with the Observable Pattern

In Java, we can very quickly fall into callback hell with anonymous classes, interfaces, etc… all of fairly heavy or verbose manner. Also Android imposes some rules (resource management, activity lifecycle and more…). The HandlerThread and Looper classes from Android are good to give the hand back for background stuff. But it’s doesn’t avoid you to build background multitask processing without the old java Thread stuff. Writing a multitasking system without a good abstraction layer is always a tedious challenge.

The first thing to do in this situation is to take a step back from this old imperative code, to see how to deal with Observables. Rather than directly calling a method, you define a mechanism for retrieving and transforming the data (the “Observable”) and then subscribe an “Observer” to it. The Observable will fires events with the Observer’s entry to capture and respond to its emissions whenever they are ready. A very good advantage of this approach is that, when you have a bunch of tasks that are not interdependent, you can start them all at the same time rather than waiting for each other to finish before starting. Another one is the ability to control the data flow between components: if your subscriber goes down, you won’t fire any notification.

The Observable pattern is the heart of RxJava framework:

Rx extends the Observer pattern to support sequences of data/events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety and concurrent data structures.  RxJava

Let’s begin to unlock the Observables and reduce the complexity under the hood. The retrofit framework (updated to version 2.x) can directly handle Observable responses and help us considerably reduce our work (we add a new RxJavaCallAdapterFactory in MainModule.java):

retrofit2_build

Now, our network calls can handle directly Observables (WeatherWS.java):

retrofit_rx

In the end, our geocode method from the SDK is reduced to this (WeatherSDK.java):

SDK_Rx

The SDK code is greatly improve because we retrofit make the job for us: it encapsulates its responses as Observables.

Asynchronous & functional programming

There are many terms used to describe this model of asynchronous programming and design. Here we use the following Rx terminology: an Observer subscribes to an Observable. An Observable emits items or sends notifications to its Observers by calling the Observers’ methods. Now we can compose Observables, Observers and functional approach that deals with immutable sequence of data.

Let’s see the app with RxJava (MainActivity.java):

App_Rx

This code still looks complex (java verbosity), but we now have now the possibility to chain functions and think in terms of data stream: we firstly map a function to extract location from Geocode data (from first call). We then reuse the location to continue the stream to ask the its GPS coordinate (with a switchMap, help us to  maintain the observable chain by reusing the result from first observable and chain it with a second observable). And then we subscribe on Observer to handle the final result of this stream (the weather itself).

Lambdas fit well with functional things, but are not available until Android 8 (Nougat). In Kotlin, you would have it in few lines 😉

App_Rx_Kotlin

It’s an important thing to be able to separate plumbing and business logic. It help make it more readable and easier to test and maintain. The first benefits that you can feel is the friendly callbacks that we can now provide. You can also make smarter things with error handling and avoid dirty try catch that don’t know what to do with.

You also gain access to smart multitasking facilities by assigning schedulers. You don’t have to bother about threading anymore: WeatherSDK.java defines a background thread and the callback thread with the subscribeOn and observeOn methods.

SDK_Rx

Behind the scenes: Reactive Streams

Elsewhere you will see that what we are calling “Observer” is sometimes called a “subscriber,” “watcher,” or “reactor.” In general we often refer to the same “reactor pattern”.

Asynchrony is needed in order to enable the parallel use of computing resources, on collaborating network hosts or multiple CPU cores within a single machine.  http://www.reactive-streams.org

The big picture to keep in mind is that Reactive Streams represents a sequence of events (the stream), and two protagonists (Observable and an Observer to those events). Beware of not confusing with java.util.Stream from Java 8, which is a collection wrapper to perform functions on it.

Sebastien Deleuze greatly explains what are reactive types:

Reactive types are not intended to allow you to process your requests or data faster, in fact they will introduce a small overhead compared to regular blocking processing. Their strength lies in their capacity to serve more request concurrently, and to handle operations with latency, such as requesting data from a remote server, more efficiently. They allow you to provide a better quality of service and a predictable capacity planning by dealing natively with time and latency without consuming more resources. Unlike traditional processing that blocks the current thread while waiting a result, a Reactive API that waits costs nothing, requests only the amount of data it is able to process and bring new capabilities since it deals with stream of data, not only with individual elements one by one.

The other great idea behind the specification is to define back pressure: a way to ensure a fast publisher doesn’t overflow a slow subscriber. Back pressure provides resilience by ensuring that all participants in a stream-based system participate in flow control to ensure steady state of operation and graceful degradation.

To continue the exploration of the reactive streams API, go with “A journey into reactive streams” from Kevin Webber. Also keep an eye on very good “notes on reactive programming” from Dave Syer. I also encourage you to read some of the articles about RxJava, from Dan Lew: “Grokking RxJava” series, “Error handling in RxJava” or “Don’t break the chain: use Rx compose operator“.

Your journey just begins

You won’t solve all your problem with a reactive approach. Sometimes AsyncTask or a good use of Handler will be just the right answer. RxJava fit well with Android, and is really smooth if you use Kotlin. We must think in terms of how data structures are composed rather than the sequence in which they execute, and we will clearly realize gains (performances, testability, robustness…). This is an entire mindset to build and a way to better see our software designs. Hope it help you have clearer ideas and let you to begin design reactive api 😉

Arnaud Giuliani Author: Arnaud Giuliani

French Java Software Tech, create and run #java #server gears (distributed and other under the hood stuffs). Also like to make #android apps

Like it?  Share  it!

Share Button

2 Comments

  1. Why switchMap and not simply a flatMap?
    SwithMap keep order after the second operation ( getWeather in this case ) in case you got more of one results from the first observable, and it’s not the case.

    You really could use Single instead of Observable for network requests because there is no possibility of having more than one result.

    • Arnaud Giuliani

      Thanks for your feedback, don’t hesitate to make a PR on github.
      Yes, you’re right we have only one result here. The example tries to show multiple subsystem coordination. My weather app is a bit simplistic then, because we want to consolidate one weather object data.

      The switchMap is like the flatMap but it will only emit items from the new observable until a new event is emitted from the source observable. It help to chain the two streams.

What do  You  think? Write a comment!

Leave a Reply

Required fields are marked *.


CommentLuv badge