Reactive Programming with RxAndroid in Kotlin: An Introduction

Learn about how Reactive programming is a whole new paradigm using RxJava and RxAndroid in Android with Kotlin. By Kyle Jablonski.

Leave a rating/review
Download materials
Save for later
Share

Update note: This tutorial has been updated to Kotlin 1.3, Android 28 (Pie), and Android Studio 3.3.2 by Kyle Jablonski. This tutorial has previously been updated to Kotlin, Android 26 (Oreo), and Android Studio 3.0 Beta 5 by Irina Galata. The original tutorial was written by Artem Kholodnyi.

Reactive programming is not just another API. It’s a whole new programming paradigm concerned with data streams and the propagation of change. You can read the full definition of reactive programming, but you will learn more about being reactive, below.

RxJava is a reactive implementation to bring this concept to the Android platform. Android applications are a perfect place to start your exploration of the reactive world. It’s even easier with RxAndroid, a library that wraps asynchronous UI events to be more RxJava like.

Don’t be scared — I’ll bet you already know the basic concepts of reactive programming, even if you are not aware of it yet!

Note: This tutorial requires good knowledge of Android and Kotlin. To get up to speed, check out our Android Development Tutorials first and return to this tutorial when you’re ready.

In this RxAndroid tutorial for reactive programming, you will learn how to do the following:

  • Grasp the concepts of Reactive Programming.
  • Define an Observable.
  • Turn asynchronous events like button taps and text field context changes into observable constructs.
  • Transform and filter observable items.
  • Leverage Rx threading in code execution.
  • Combine several observables into one stream.
  • Turn all your observables into Flowable constructs.
  • Use RxJava’s Maybe to add a favorite feature to the app.

I hope you are not lactose intolerant — because you’re going to build a cheese-finding app as you learn how to use RxJava! :]

Getting Started

Download cheesefinder-starter and open it in Android Studio 3.3.2 or above.

You’ll be working in both CheeseActivity.kt and CheeseAdapter.kt. The CheeseActivity class extends BaseSearchActivity; take some time to explore BaseSearchActivity and check out the following features ready for your use:

  • showProgress(): A function to show a progress bar…
  • hideProgress(): … and a function to hide it.
  • showResult(result: List): A function to display a list of cheeses.
  • cheeseSearchEngine: A field which is an instance of CheeseSearchEngine. It has a search function which you call when you want to search for cheeses. It accepts a text search query and returns a list of matching cheeses.

Build and run the project on your Android device or emulator. You should see a gloriously empty search screen:

Of course, it’s not going to stay like that forever, you’ll soon begin adding reactive functionality to the app. Before creating your first observable, indulge yourself with a bit of theory first.

What is Reactive Programming?

In imperative programming, an expression is evaluated once and the value is assigned to a variable:

var x = 2
var y = 3
var z = x * y // z is 6

x = 10
// z is still 6

On the other hand, reactive programming is all about responding to value changes.

You have probably done some reactive programming — even if you didn’t realize it at the time.

  • Defining cell values in spreadsheets is similar to defining variables in imperative programming.
  • Defining cell expressions in spreadsheets is similar to defining and operating on observables in reactive programming.

Take the following spreadsheet that implements the example from above:

The spreadsheet assigns cell B1 with a value of 2, cell B2 with a value of 3 and a third cell, B3, with an expression that multiplies the value of B1 by the value of B2. When the value of either of the components referenced in the expression changes, the change is observed and the expression is re-evaluated automagically in B3:

The idea of reactive programming, to put it simply, is to have components which form a larger picture – which can be observed. And have your program listen to, and consume the changes whenever they happen.

Difference Between RxJava and RxKotlin

As you probably know, it’s possible to use Java libraries in Kotlin projects thanks to Kotlin’s language compatibility with Java. If that’s the case, then why was RxKotlin created in the first place? RxKotlin is a Kotlin wrapper around RxJava, which also provides plenty of useful extension functions for reactive programming. Effectively, RxKotlin makes working with RxJava no less reactive, but much more Kotlin-y.

In this article, we’ll focus on using RxJava, since it’s critical to understand the core concepts of this approach. However, everything you will learn applies to RxKotlin as well.

Note: Take a look at the build.gradle file and the project dependencies especially. Except for the UI libraries, it contains RxKotlin and RxAndroid packages. We don’t need to specify RxJava here explicitly since RxKotlin already contains it.

RxJava Observable Contract

RxJava makes use of the Observer pattern.

Note: To refresh your memory about the Observer pattern you can visit Common Design Patterns for Android with Kotlin.

In the Observer pattern, you have objects that implement two key RxJava interfaces: Observable and Observer. When an Observable changes state, all Observer objects subscribed to it are notified.

Among the methods in the Observable interface is subscribe(), which an Observer will call to begin the subscription.

From that point, the Observer interface has three methods which the Observable calls as needed:

  • onNext(T value) provides a new item of type T to the Observer.
  • onComplete() notifies the Observer that the Observable has finished sending items.
  • onError(Throwable e) notifies the Observer that the Observable has experienced an error.

As a rule, a well-behaved Observable emits zero or more items that could be followed by either completion or error.

That sounds complicated, but some marble diagrams may clear things up.

network-request

The circle represents an item that has been emitted from the observable and the black block represents a completion or error. Take, for example, a network request observable. The request usually emits a single item (response) and immediately completes.

A mouse movement observable would emit mouse coordinates but will never complete:

mouse-coords

Here you can see multiple items that have been emitted but no block showing the mouse has completed or raised an error.

No more items can be emitted after an observable has completed. Here’s an example of a misbehaving observable that violates the Observable contract:

misbehaving-stream

That’s a bad, bad observable because it violates the Observable contract by emitting an item after it signaled completion.

Kyle Jablonski

Contributors

Kyle Jablonski

Author

Filip Babić

Tech Editor and Final Pass Editor

Tyler Bos

Editor

Over 300 content creators. Join our team.