In case you haven’t heard: RxJava2 was released sometime back. RxJava 2 was a massive rewrite with breaking apis (but for good reasons). Most dependent libraries have upgraded by now though, so you’re safe to pull that migration trigger with your codebases.

Folks starting out directly with Rx2 might enjoy this guide but it’s the ones that started with Rx 1 that will probably appreciate it the most.

This is a continuation post in a 2 part series:

  1. Understanding the changes
  2. Disposing subscriptions

Let’s get started.

In this first part, I want to dive into making sense of the Rx2 changes from the point of view of an Rx1 user.

Why things changed with RxJava2

tl;dr- Reactive Streams spec

Reactive Streams is a standard for doing “reactive” programming and RxJava now implements the Reactive Streams specs with version 2.x. RxJava was sort of a trailblazer in reactive programming land but it wasn’t the only library around. There were others that also dealt with reactive paradigms. But with all the libraries adhering to the Reactive Streams spec now, interop between the libraries is a tad bit easier.

The spec per say is pretty straightforward with just 4 interfaces:

  1. Publisher (anything that publishes events, so Observable,Flowable etc. - more on this later)
  2. Subscriber (anything that listens to a Publisher)
  3. Subscription (Publisher.subscribe(Subscriber) => Subscription when you join a Publisher and a Subscriber, you are given a connection also called a Subscription)
  4. Processor (a Publisher + a Subscriber, sound familiar? yep Subjects for us RxJava 1 luddites)

If you’re slightly more curious about the design goals, I also suggest the following resources:


We should probably get one important change out of the way:

Dependency change

Search:

compile "io.reactivex:rxjava:${rxJavaVersion}"
compile "io.reactivex:rxandroid:${rxAndroidVersion}"

compile "com.jakewharton.rxbinding:rxbinding:${rxBindingsVersion}"
compile "com.squareup.retrofit2:adapter-rxjava:${retrofit2Version}"

Replace:

compile "io.reactivex.rxjava2:rxjava:${rxJavaVersion}"
compile "io.reactivex.rxjava2:rxandroid:${rxAndroidVersion}"

compile "com.jakewharton.rxbinding2:rxbinding:${rxBindingsVersion}"
compile "com.squareup.retrofit2:adapter-rxjava2:${retrofit2Version}"

A minor change in your gradle dependency pull (“2” suffix).

The actual classes though have been moved to a new package internally io.reactivex (vs rx). So you’ll have to change those import statements.

Also you “could” theoretically have both Rx1 and Rx2 running simultaneously but this is a bad idea because certain primary constructs like Observables have a very different notion of handling streams (backpressure). It can be a nightmare during that interim period where you have to remember the behavior differences. Also if you happen to use both Rx1 and Rx2 Observables you have to be careful about qualifying them explicitly with the right package name (rx.Observable or io.reactivex.Observable). This is very easy to mix up and get wrong.

Bite the bullet and migrate it all in one shot.

Another super important change:

Observable -> Flowable

Search : `import rx.Observable;`
Replace: `import io.reactivex.Flowable;`
  • Flowable is the new Observable. Succinctly - it’s a backpressure-enabled base reactive class.
  • You want to be using Flowable everywhere now, not Observable. Use this as your default.
  • Observables are still available for use, but unless you really understand backpressure, you probably don’t want to be using them anymore.

Flowable = Observable + backpressure handling

Note on “Publisher"s:

Remember Publisher? it’s basically the Reactive Streams interface for anything that produces events (Reread the Reactive Streams spec section above if this is not making sense).

Flowable implements Publisher. This is our new base default reactive class and implements the Reactive Streams spec 1 <-> 1. Think of of Flowable as primero uno “Publisher” (this is also partly the reason I recommend Flowable as the new default, in the previous section).

The other base reactive classes that are Publishers include Observable, Single, Completable and Maybe. But they don’t implement the Publisher interface directly.

Why you ask?

Well the other base classes are now considered “Rx” specific constructs with specialized behavior pertaining to Rx. These are not necessarily notions you would find in the Reactive Streams specs.

We can look at the actual interface declarations and it’ll be clear.

Note on “Subscriber"s:

So if Publisher is the Reactive Streams event producer, Subscriber is the Reactive Streams event “listener” (it’s extremely helpful to keep these terms firmly grounded in our heads, hence the incessant repetition).

Looking at the actual interface code declaration should offer more clarity to the above two sections.

// Reactive Streams spec

// Flowable implements Publisher

interface Publisher<T> {
    void subscribe(Subscriber<? super T> s);
}

As noted before, Publisher and Subscriber are part of the Reactive Streams spec. Flowable -which is now numero uno base reactive class of choice- implements Publisher. All good so far.

But what about the other base reactive classes like Observable and Single that we’ve come to love and use?

On the publishing side, instead of implementing the standard Publisher interface the other event producers implement a “similar” interface.

// RxJava specific constructs

// Observable implements "ObservableSource"
interface ObservableSource<T> {
    void subscribe(Observer<? super T> observer);
    // notice "Observer" here vs the standard "Subscriber"
}

// Single implements SingleSource
interface SingleSource<T> {
    void subscribe(SingleObserver<? super T> observer);
}

interface CompletableSource {
    void subscribe(CompletableObserver observer);
}

interface MaybeSource<T> {
    void subscribe(MaybeObserver<? super T> observer);
}

Notice: instead of having the standard Subscriber (Reactive Streams standard) the other base reactive classes (Observable, Single etc.) now have corresponding “special” Rx specific Subscriber or event listeners called “Observer"s.

That’s it for Part 1. In the next part, we’ll look at disposing subscriptions.

My thanks to David Karnok & Donn Felker for reviewing this post.