A few weeks ago, the release of RxJava 2.0.0 was announced. It has been completely written from scratch, around the Reactive Streams specification.

Backpressure

We discussed the Reactive Streams initiative in Java 9 series: Concurrency Updates. It is an initiative that provides a standard for asynchronous stream processing with non-blocking backpressure. Backpressure is a way to control the amount of data sent in the stream, in order not to overwhelm the receiver. In order to achieve this, a publish-subscribe messaging pattern is used.

RxJava 1.x did not implement the Reactive Streams API, as it predates it, but does use a non-blocking ‘pull’ approach to utilise backpressure and control the data flow. An “observer” subscribes to an Observable, and waits for the Observable to emit items, reacting when it happens. Instead of calling a method on an action, the observer subscribes to an “Observable” and reacts to events as and when they occur.

As RxJava 2.0 has been rewritten, there are some major changes between 1.x and 2.x code. Here is a brief run-down of a few of them:

When backpressure isn’t working

In RxJava 2.x, there is io.reactivex.Observable. This is now non-backpressured. This may be needed if you have less than 1000 elements at the most, or infrequent events such as UI interactions. This allows for situations where backpressure isn’t constant, or high intensity.

Controlling flow

io.reactivex.Flowable is now the backpressure enabled operator that can handle over 10,0000 elements, and is optimised for reading files from disk, database entries and streaming.

Null

null values will no longer be accepted, for example Observable.just(null) and Single.just(null) will cause NullPointerExceptions.

Single

This is a special version of an Observable that only emits one item. In 1.x, there were only two methods required rather than the standard three (onNext, onError, onCompleted). They are:

  • onSuccess (passed to the single item emitted)
  • onError (if the Single is unable to emit an item)

In 2.x, the consumer type is the interface io.reactivex.SingleObserver<T> that has three methods:

  • onSubscribe
  • onSuccess
  • onError

Maybe

This is a new base reaction type, that is a way to capture an emission pattern where there could be an item, no items or an error. It has no notion of backpressure, and as there is only one item, onSuccess is called rather than onComplete.

Other changes

There are a number of important changes, such as 1.x’s TestSubject being dropped, renamed classes (to reflect the division between Observable and Flowable), and the implementation of Subjects and Processors. Switching from 1.x to 2.x is not simple and the two versions are very different, so it requires careful reading.

Further reading