---
title: Demystifying Reactive Android Apps
teaser: 'Writing reactive applications can be intimidating, so here''s a step by step
  guide to get you off the ground.

  '
tags: android,rxjava
author: Alex Sullivan
published_on: 2019-05-03
---

Many of us in the Android community have been using
[RxJava](https://github.com/ReactiveX/RxJava) to perform complex
asynchronous tasks but have often fallen short of using it to create a truly
reactive application.

In this post, we'll walk through implementing a feature of an Android TODO app
in a reactive manner, touching on some of the places where people typically
diverge from a true reactive flow.

### What is reactive programming?

Before we get started, let's take a moment to outline what reactive programming
is. At its core, reactive programming is a style of programming wherein data is
represented as streams of information that a program can easily react to.
Manifestations of reactive programming often rely heavily on the observer
pattern; wherein some object has a list of observers that it notifies about
changes in its internal state. For RxJava, the observers in question are the
objects calling `subscribe` on an `Observable`.

## Components outline

Before we dive into the code, it's worth touching on the architecture the app
uses. Most of the pieces won't be anything new to the average Android developer,
but the way they interact with each other may be.

There's a **ViewModel**, which drives UI logic. It typically observes a
**Repository** which makes network or database calls and handles business logic
that is less directly related to the UI. And there is of course a **View**,
usually represented by an Android `Activity` or `Fragment`.

## Diving in

To demonstrate building a feature in a reactive manner, we'll focus in on a
theoretical feature of our TODO app that allows a user to view their "top" TODO
for the day.

You'll need an object to model a todo:

```kotlin
data class Todo(val title: String, val dueDate: Date, val isComplete: Boolean)
```

You'll need some data layer component that can fetch the top todo
and save an updated todo:

```kotlin
interface TopTodoService {
  fun topTodo(): Single<Todo>
  fun saveTodo(todo: Todo): Completable
}
```

The data layer could be saving to a database or fetching from a network; it's
not particularly important. All that matters is that it implements the above
interface.

At this point it's worth taking a minute to recognize that just because the
`TopTodoService` exposes RxJava types for its methods **does not mean it's
exposing a reactive API**. A reactive
API should allow a consumer to observe or listen for some change whenever a
change is made to the internal state of whatever the API is exposing.

Here's a (contrived) example of a non reactive repository that wraps the
`TopTodoService`:

```kotlin
class NonReactiveRepository(private val service: TopTodoService) {
  fun fetchTopTodo(): Single<Todo> {
    return service.topTodo()
  }

  fun saveTopTodo(todo: Todo): Completable {
    return service.saveTodo(todo)
  }
}
```

Calling `fetchTopTodo` on this repository should theoretically give you the top
TODO for the day. However, if you're calling `fetchTopTodo` from your
**ViewModel** you'll need to make sure to re-query it whenever the top TODO is
updated. That means you need to keep track of where in your code you're updating
that TODO, and you need to make sure you're always remembering to update the UI
whenever those changes are made.

In a truly reactive system, you're observing _streams_ of data, so you know
you're always operating on the most up to date information the system can
provide.

You know this isn't a truly reactive API because `fetchTopTodo` returns a
`Single`. You can't model a stream of information with a `Single`, so that's a
good hint that you'll need to do a bit more work to expose a genuinely reactive
API.

## Creating a reactive API

Instead, here's a truly reactive wrapper around `TopTodoService`:

```kotlin
class TopTodoRepository(private val service: TopTodoService) {
  private val disposables = CompositeDisposable()
  private val topTodoSubject = BehaviorSubject.create<Todo>()
  val topTodoObservable = topTodoSubject.hide()

  init {
    fetchTopTodo()
  }

  private fun fetchTopTodo() {
    service
      .topTodo()
      .subscribeOn(Schedulers.io())
      .subscribe(topTodoSubject::onNext)
      .addTo(disposables)
  }

  fun completeTodo(todo: Todo) {
    val completedTodo = todo.copy(isComplete = true)
    service.saveTodo(completedTodo)
      .subscribeOn(Schedulers.io())
      .subscribe { topTodoSubject.onNext(completedTodo) }
      .addTo(disposables)
  }
}
```

The above repository works such that whenever `completeTodo` is called, a new
value is piped through the `topTodoSubject`. It will also immediately send a new
`Todo` through `topTodoSubject` as soon as `TopTodoRepository` is created. As a
result, any class that uses the `TopTodoRepository` can subscribe to the
`topTodoObservable` and will receive a steady stream of whatever the top `Todo`
is, even as the top `Todo` changes!

By exposing all of the repositories state in a single observable, your
**ViewModel** becomes entirely a function of the `TopTodoRepository`'s
observable:

```kotlin
class TopTodoViewModel(val repo: TopTodoRepository): ViewModel() {
  private val disposables = CompositeDisposable()
  val dueDateLiveData = MutableLiveData<Date>()
  val titleLiveData = MutableLiveData<String>()
  val isCompleteLiveData = MutableLiveData<Boolean>()

  init {
    val todoObservable = repo.topTodoObservable
      .subscribeOn(Schedulers.io())
      .share()

    todoObservable
      .map { it.copy(dueDate = Date()) }
      .map { it.dueDate }
      .subscribe(dueDateLiveData::postValue)
      .addTo(disposables)

    todoObservable
      .map { it.title }
      .subscribe(titleLiveData::postValue)
      .addTo(disposables)

    todoObservable
      .map { it.isComplete }
      .subscribe(isCompleteLiveData::postValue)
      .addTo(disposables)
  }
}
```

Critically, the above will keep the UI up to date as the internal state of the
repo changes.

## Responding to user actions

Consuming information is one thing, but the above code doesn't deal with
changing the state of the world at all. Imagine we have some view on the screen
that when clicked should mark a `Todo` as completed.

Ultimately it's the **View** that will invoke this action, so we need some way
for the **View** to communicate that action with the **ViewModel**.

At first pass the answer seems obvious. Simply add a public function to the
**ViewModel** that calls into the repo:

```kotlin
fun todoCompleted() {
  repo.completeTodo(???)
}
```

However, at this point you don't know what the `Todo` is that should be updated.

You have a few options:

1. You could send the initial `Todo` over to the **View** when it's
   first loaded so the **View** can then bubble it back up to the **ViewModel**
   when the completion action is taken.
2. You can subscribe to the `todoObservable` in the **ViewModel** and save the
   currently displayed `Todo` and use that when `todoCompleted` is called
3. You could flip the table around and expose whatever click listener calls
   `todoCompleted` as an observable and pass that into the view model.

The first option violates the single responsibility principle. Ideally the
**View** has no insight into the business objects.

The second option, keeping a local copy of the `Todo`, solves the single
responsibility violation introduced in the first option, but it has the downside
of introducing mutable state to your view model. You'd have to make sure that
your local copy of the `Todo` object is always up to date and is never updated
incorrectly.

The third option, treating a view like an observable, is absolutely a viable
approach to take. However, it too comes with several downsides:

- If you're going to make an observable out of a click listener, you need to be
  aware of the threading limitations that come with interacting with views.
  Specifically, you need to make sure that the piece adding the click listener
  does so on the main thread.
- Since most Android views can only have one associated click listener, you'll
  only be able to subscribe to the observable once before you start overwriting
  other subscriptions. You can avoid this by using the `share` operator, but
  it's a hidden trap to fall into.

There is also a surprise fourth option: stop treating click listeners any
different than the other dynamic properties you're updating!

Just like you'd send a `String` to be displayed in a `TextView` via a `LiveData`
stream, you can send a `ClickListener` function to the **View** via a `LiveData`
object.

```kotlin
val finishedTaskClickListenerLiveData = MutableLiveData<() -> Unit>()

todoObservable
  .subscribe { todo ->
    finishedTaskClickListenerLiveData.postValue {
      repo.completeTodo(todo)
    }
  }
  .addTo(disposables)
```

Now the `finishedTaskClickListenerLiveData` will deliver a function that calls
`repo.completeTodo` with the correct `Todo`. There's no special logic to handle
click listeners; it's just another mutable property of a view that you deliver
via `LiveData`.

## The View

Building out the **View** is now straightforward. All it involves is subscribing
to the `LiveData`s that the **ViewModel** exposes:

```kotlin
class TopTodoActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val repo = TopTodoRepository(FakeService())
    val viewModel = TopTodoViewModel(repo)

    viewModel.dueDateLiveData.observe(this, Observer {
      dueDate.text = it?.toString()
    })
    viewModel.titleLiveData.observe(this, Observer {
      titleText.text = it
    })
    viewModel.isCompleteLiveData.observe(this, Observer {
      isFinished.text = if (it!!) { "Done!" } else { "Not Done!" }
    })
    viewModel.finishedTaskClickListenerLiveData.observe(this, Observer { click ->
      finishedTaskButton.setOnClickListener { click?.invoke() }
    })
  }
}
```

The only novel piece of code here is the last observing block:

```kotlin
viewModel.finishedTaskClickListenerLiveData.observe(this, Observer { click ->
  finishedTaskButton.setOnClickListener { click?.invoke() }
})
```

The `finishedTaskClickListenerLiveData` delivers a `LiveData<() -> Unit>`, which
the **View** then observes. Since `setOnClickListener` expects a function of
type `(View) -> Unit`, you'll have to create a new `OnClickListener` and
manually invoke the delivered function. This can be easily cleaned up with a
simple extension method, but that's out of scope for this blog post.

## Wrapping up

Utilizing a reactive architecture can simplify your application's logic and
guarantee that your users are seeing the most up to date information. But it
take's some effort to ensure that you're getting the most out of your app's
RxJava and LiveData usage. In general, make sure to:

- Verify that any data that can change is represented as an `Observable<Data>`
  rather than a `Single`.
- Aim to have your business logic components expose observables that represent
  their state rather than passing those observables back up through to the view
  or viewmodel.
- Try and construct your view models such that they could theoretically be
  written entirely in the `init` block. That's not to say that you _should_
  just put everything in the `init` block, but if you're finding that you don't
  have the information you need to model the inputs and outputs of your view
  model in the `init` block you may be missing a reactive piece in your system.
