Unraveling RxJava and its usage in Android

Using RxJava to make your life easier

on

What on earth is RxJava?

RxJava is a library for constructing asynchronous and event-based programs by using observable sequences. Rx stands for reactive extensions and was first developed by the folks at Microsoft. Since then, it has been universally adopted by the programming world because of its proven effectiveness in handling complex asynchronous tasks.

You can think of  RxJava as a routine with three main constructs:

  • Observable – Mechanism where all the main processing happens and which continuously shoots updates.
  • Observer – Mechanism that listens to the updates and execute them when a connection is established.
  • Scheduler – Mechanism to establish a connection between Observable and Observer

I will go into detail about each construct and what it is used for in the following blog posts.

Why do I need RxJava for Android?

If you have had some experience as a developer in android or  java for that matter, you would have definitely come across situations where you need to display some data while you are simultaneously loading it, these types of events are called concurrent events and can sometimes cause UI freezes if not handled properly. The most common solutions that developers use, to handle this kind of events in functional programming, are Threads and Futures. In android specifically, AsyncTasks are used widely to handle these events, where a job runs in the background and the UI is updated after the job completes.

a. Normal implementation of download task with AsyncTask

class DownloadFileTask extends AsyncTask<String, Void, File> {

  protected File doInBackground(String... args) {
    final String url = args[0];
    try {
      byte[] fileContent = downloadFile(url);
      File file = writeToFile(fileContent);
      return file;
    } catch (Exception e) {
      // ???
    }
  }

  protected void onPostExecute(File file) {
    Context context = getContext(); // ???
    Toast.makeText(context,
        "Downloaded: " + file.getAbsolutePath(),
        Toast.LENGTH_SHORT)
        .show();
  }
}

Now consider a scenario in which you have to perform multiple concurrent events and simultaneously update their results to UI. Since, in android, not more than 5 AsyncTasks can run concurrently, you have been limited. Also, if there is any error while executing a background task you would never know until the end of execution. These issues unnecessarily make something as common as managing asynchronous tasks, tedious and difficult for developers. This is where RxJava comes to the rescue.

If your app needs to make HTTP requests to fetch data, Rx’s Observables will be your saviour and will provide fully asynchronous behaviour without you having to deal with threading and synchronisation. It is very simple to wrap an Android HttpURLConnection in an Observable when using RxJava for Android.

b. Implementation of download task with a Rx’s Observable

private Observable<File> downloadFileObservable() {
    return Observable.create(new OnSubscribeFunc<File>() {
        @Override
        public Subscription onSubscribe(Observer<? super File> fileObserver) {
            try {
                byte[] fileContent = downloadFile();
                File file = writeToFile(fileContent);
                fileObserver.onNext(file);
                fileObserver.onCompleted();
            } catch (Exception e) {
                fileObserver.onError(e);
            }
            return Subscriptions.empty();
        }
    });
}

This is just partial code for the whole implementation which looks  just as clean as expected. In the example we are considering, the Observable stream emits a single item to which a File observer can connect. Whenever this observable is subscribed to, its onSubscribe function triggers and executes the task at hand. If the task can be carried out successfully, deliver the result to the observer through onNextso onNext can properly react to it. Then signal completion by using onCompleted If an exception is raised, deliver it to the observer through onError As an example, you can use this from a Fragment

class MyFragment extends Fragment implements Observer<File> {
  private Subscription subscription;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    subscription = AndroidObservables.fromFragment(this, downloadFileObservable())
                          .subscribeOn(Schedulers.newThread())
                          .subscribe(this);
  }

  private Observable<File> downloadFileObservable() { /* as above */ }

  @Override
  protected void onDestroy() {
    subscription.unsubscribe();
  }

  public void onNext(File file) {
    Toast.makeText(getActivity(),
        "Downloaded: " + file.getAbsolutePath(),
        Toast.LENGTH_SHORT)
        .show();
  }

  public void onCompleted() {}

  public void onError(Throwable error) {
    Toast.makeText(getActivity(),
        "Download failed: " + error.getMessage(),
        Toast.LENGTH_SHORT)
        .show();
  }
}

The example above just goes to show how easy and clean it is to implement a Rx Observable pattern and use it in your android app. If you are interested in checking out, more RxJava Android samples please check out this extremely useful GitHub repo by Kaushik Gopal. Also, do check out RxAndroid Github repo which more or less includes all android specific bindings for RxJava.

Resources

RxAndroidBootsrap – Github

RxAndroidLibs – Github

RxAndroidEventsSample – Github

Kartik is a seasoned android developer with a weird obsession for cornflakes.

2 thoughts on “Unraveling RxJava and its usage in Android Using RxJava to make your life easier

    1. Yes jason ! There will be a subsequent post to this post in which in which i will cover the RxJava in more detail and explain the 3 constructs. Please subscribe to receive the new post whenever it is published.

Please share your comments