The RxJava Android Module

David Gross edited this page Sep 4, 2015 · 11 revisions

Note: This page is out-of-date. See the RxAndroid wiki for more up-to-date instructions.


The rxjava-android module contains Android-specific bindings for RxJava. It adds a number of classes to RxJava to assist in writing reactive components in Android applications.

  • It provides a Scheduler that schedules an Observable on a given Android Handler thread, particularly the main UI thread.
  • It provides operators that make it easier to deal with Fragment and Activity life-cycle callbacks.
  • It provides wrappers for various Android messaging and notification components so that they can be lifted into an Rx call chain
  • It provides reusable, self-contained, reactive components for common Android use cases and UI concerns. (coming soon)

Binaries

You can find binaries and dependency information for Maven, Ivy, Gradle and others at http://search.maven.org.

Here is an example for Maven:

<dependency>
    <groupId>io.reactivex</groupId>
    <artifactId>rxandroid</artifactId>
    <version>0.23.0</version>
</dependency>

…and for Ivy:

<dependency org="io.reactivex" name="rxandroid" rev="0.23.0" />

The currently supported minSdkVersion is 10 (Android 2.3/Gingerbread)

Examples

Observing on the UI thread

You commonly deal with asynchronous tasks on Android by observing the task’s result or outcome on the main UI thread. Using vanilla Android, you would typically accomplish this with an AsyncTask. With RxJava you would instead declare your Observable to be observed on the main thread by using the observeOn operator:

public class ReactiveFragment extends Fragment {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Observable.from("one", "two", "three", "four", "five")
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(/* an Observer */);
}

This executes the Observable on a new thread, which emits results through onNext on the main UI thread.

Observing on arbitrary threads

The previous example is a specialization of a more general concept: binding asynchronous communication to an Android message loop by using the Handler class. In order to observe an Observable on an arbitrary thread, create a Handler bound to that thread and use the AndroidSchedulers.handlerThread scheduler:

new Thread(new Runnable() {
    @Override
    public void run() {
        final Handler handler = new Handler(); // bound to this thread
        Observable.from("one", "two", "three", "four", "five")
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.handlerThread(handler))
                .subscribe(/* an Observer */)

        // perform work, ...
    }
}, "custom-thread-1").start();

This executes the Observable on a new thread and emits results through onNext on custom-thread-1. (This example is contrived since you could as well call observeOn(Schedulers.currentThread()) but it illustrates the idea.)

Fragment and Activity life-cycle

On Android it is tricky for asynchronous actions to access framework objects in their callbacks. That’s because Android may decide to destroy an Activity, for instance, while a background thread is still running. The thread will attempt to access views on the now dead Activity, which results in a crash. (This will also create a memory leak, since your background thread holds on to the Activity even though it’s not visible anymore.)

This is still a concern when using RxJava on Android, but you can deal with the problem in a more elegant way by using Subscriptions and a number of Observable operators. In general, when you run an Observable inside an Activity that subscribes to the result (either directly or through an inner class), you must unsubscribe from the sequence in onDestroy, as shown in the following example:

// MyActivity
private Subscription subscription;

protected void onCreate(Bundle savedInstanceState) {
    this.subscription = observable.subscribe(this);
}

...

protected void onDestroy() {
    this.subscription.unsubscribe();
    super.onDestroy();
}

This ensures that all references to the subscriber (the Activity) will be released as soon as possible, and no more notifications will arrive at the subscriber through onNext.

One problem with this is that if the Activity is destroyed because of a change in screen orientation, the Observable will fire again in onCreate. You can prevent this by using the cache or replay Observable operators, while making sure the Observable somehow survives the Activity life-cycle (for instance, by storing it in a global cache, in a Fragment, etc.) You can use either operator to ensure that when the subscriber subscribes to an Observable that’s already “running,” items emitted by the Observable during the span when it was detached from the Activity will be “played back,” and any in-flight notifications from the Observable will be delivered as usual.

See also