compile 'io.reactivex.rxjava2:rxjava:2.0.0'

RxJava 2.x

Overview

  • Currently @ 2.0.0-RC4
  • The next major version of RxJava
  • Breaking changes
  • 1.x and 2.x can live in parallel
  • Rewritten implementation
    • Conforms to the Reactive Streams protocol
    • Improved implementation, fixing 1.x mistakes

Reactive Streams (RS)

  • Open, industry standard way of doing async streams on the JVM
  • RS is a result of a joint effort, included RxJava devs
  • The Java 9 Flow API = RS in JDK
  • 2.x confroms to RS and Flow - 1.x does not
  • Converter module that makes 1.x RS-compliant

What does this mean?

  • RS is the standard interface
  • We already have multiple implementations, /w different capabilities
    • RxJava 2.x
    • Akka Streams
    • Reactor
    • ... ?

RxJava 2.x traits

  • Truly a reactive EXTENSION
  • Lightweight (only depends on Reactive Extensions)
  • Non-opinionated implementation of async streams
  • Collections of useful higher order functions
  • With parameeterized concurrency
  • Ever-growing community, great support and heavily tested

Changes

Null events -> nope

  • No .onNext(null) -> NPE
    • We do this at a few places
  • Observalbe<Void> can only pass signals
    • Use Observable<Object> with dummy objects

Observable VS Flowable

  • Observable -> has no backpressure support
  • Flowable -> has backpressure support
  • In 1.x the Observable was retrofitted with backpressure
    • This has made a lot of people very angry and been widely regarded as a bad move
    • Random unexpected MissingBackpressureException

Reactive base types++

  • Observable (& Flowable)
  • Single
  • Maybe
  • Completable

Single

  • Protocol: onSubscribe (onSuccess | onError)?
  • Stuff that either completes with a result, or dies
  • Examples
    • HTTP GET request
    • Computation tasks, e.g. transforming Bitmaps
Single.just(1).subscribe(new SingleObserver<Integer>() {
    @Override
    public void onSubscribe(Disposable d) {
        // Subscription just happened
    }
    @Override
    public void onSuccess(Integer value) {
        // Succeeded with a value
    }
    @Override
    public void onError(Throwable e) {
        // Failed
    }
});

Maybe

  • Protocol: onSubscribe (onSuccess | onComplete | onError)?
  • Stuff that either completes with OR without a result OR dies
  • Example
    • Getting a value from a cache
DogCache.getDog("Morzsi").subscribe(new MaybeObserver<Dog>() {
    @Override
    public void onSubscribe(Disposable d) {
        // Subscription just happened
    }
    @Override
    public void onSuccess(Dog value) {
        // We got Morzsi \O/
    }
    @Override
    public void onError(Throwable e) {
        // Error during getting Mittens
    }
    @Override
    public void onComplete() {
        // Where is Morzsi? :(
    }
});

Completable

  • Protocol: onSubscribe (onComplete | onError)?
  • Stuff that either completes without a result, or dies
Completable.fromRunnable(expenseOperation).subscribe(new CompletableObserver() {
    @Override
    public void onSubscribe(Disposable d) {
        // Subscription just happened
    }
    @Override
    public void onComplete() {
        // Operation complete
    }
    @Override
    public void onError(Throwable e) {
        // Operation failed
    }
});

Subjects & Processors

  • *Subjects
    • Working as before, no backpressure support
  • *Processors
    • Same as *Subjects, WITH backpressure support
  • (Separate session about Subject behavior, tips & tricks?)

Subscriptions

Observable I.

  • New onSubscribe() callback, getting Disposable
  • We can cancel a stream right away
    • Even a fully synchronous one!
Observable.just(1, 2, 3, 4).subscribe(new Observer<Integer>() {
    @Override
    public void onSubscribe(Disposable d) {
        // Subscription just happened, we can dispose right away
    }
    @Override
    public void onNext(Integer value) {
        // Got a new event
    }
    @Override
    public void onError(Throwable e) {
        // Ended with error
    }
    @Override
    public void onComplete() {
        // Ended with completion
    }
});

Observable II.

  • .subscribe() returns a Disposable for cancellation
CompositeDisposable cd = new CompositeDisposable();
Disposable d1 = Observable.just(1).subscribe(System.out::println);
Disposable d2 = Observable.just(2).subscribe(System.out::println);
cd.add(d1);
cd.add(d2);
cd.clear();

Flowable I.

  • New onSubscribe() callback, getting a Subscription
  • Subscription combines request management with cancellation
Flowable.range(1, 2000).subscribe(new Subscriber<Integer>() {
    @Override
    public void onSubscribe(Subscription s) {
        // Subscription just happened
        s.request(5);
    }
    @Override
    public void onNext(Integer integer) {
        // Got a new event
    }
    @Override
    public void onError(Throwable t) {
        // Ended with error
    }
    @Override
    public void onComplete() {
        // Ended with completion
    }
});

Flowable II.

  • .subscribe() returns void for RS compliance
  • Use .subscribeWith() and ResourceSubscriber to remedy this of you need cancellation
CompositeDisposable cd = new CompositeDisposable();
ResourceSubscriber s1 = Flowable.range(1, 2000).subscribeWith(resourceSubscriber);
ResourceSubscriber s2 = Flowable.range(1, 2000).subscribeWith(resourceSubscriber);
cd.add(s1);
cd.add(s2);
cd.clear();

Better test tools

  • .test() returns a TestSubscriber right away for convencience!
  • Chaining TestSubscriber assert calls
  • Many extra, handy methods for assertions & testing in general
Observable.just(1, 2, 3)
        .test()
        .assertSubscribed()
        .assertResult(1, 2, 3);

Q&A

Writing operators, source-like (fromAsync) or intermediate-like (flatMap) has always been a hard task to do in RxJava. There are many rules to obey, many cases to consider but at the same time, many (legal) shortcuts to take to build a well performing code. Now writing an operator specifically for 2.x is 10 times harder than for 1.x. If you want to exploit all the advanced, 4th generation features, that's even 2-3 times harder on top (so 30 times harder in total).

What's new in RxJava 2.x?

By rzsombor

What's new in RxJava 2.x?

  • 1,535