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