Slide 1

Slide 1 text

RxJava a Java implementation of Reactive Extentions HACKATRON TALK

Slide 2

Slide 2 text

DrAL3X Mobile Developer at 
 Spreaker.com DrAL3X on ALESSANDRO CALZAVARA

Slide 3

Slide 3 text

A Library for composing asynchronous and event-based programming using observable sequences for the Java VM RXJAVA WHAT IS

Slide 4

Slide 4 text

"It extends the observer pattern to support sequences of data and/or events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety, concurrent data structures, and non-blocking I/O." @ ReactiveX.io “

Slide 5

Slide 5 text

OBSERVER PATTERN THE BASICS OF Observer: • handle notifications Subject: • register/unregister observers • notify observers

Slide 6

Slide 6 text

WHY USING RX

Slide 7

Slide 7 text

SIMPLE API EVERYTHING BEGINS WITH A public Data getData(); Owner of API should retain control of concurrency behaviour. User should simply not care how it work behind.

Slide 8

Slide 8 text

CHANGE API CHANGE INTERACTION BY single items multiple items synch T getData() Iterable getData() asynch Future getData() Observable getData()

Slide 9

Slide 9 text

ITERABLE and OBSERVABLE DUALITY BETWEEN Iterable Observable pull push T next() onNext(T) throws Exception onError(Exception) returns onCompleted()

Slide 10

Slide 10 text

T getData() SYNC SINGLE ITEM String s = getData(args); if (s.equals(x)) { // do something } else { // do something else }

Slide 11

Slide 11 text

Iterable getData() SYNC MULTIPLE ITEMS Iterable values = getData(args); for (String s : values) { if (s.equals(x)) { // do something } else { // do something else } }

Slide 12

Slide 12 text

Future getData() ASYNC SINGLE ITEM Future s = getData(args); if (s.get().equals(x)) { // do something } else { // do something else }

Slide 13

Slide 13 text

FUTURES REMOVE BLOCKING WITH Future d = getData(args); Futures.addCallback(d, new FutureCallback { public void onSuccess(String s) { if (s.equals(x)) { // do something } else { // do something else } } }, executor);

Slide 14

Slide 14 text

COMPOSABLE FUTURE REMOVE BLOCKING WITH Future d = getData(args); d.map({ s -> if (s.equals(x)) { // do something } else { // do something else } }); Only Java 8+ or Scala

Slide 15

Slide 15 text

Observable getData() ASYNC MULTIPLE ITEMS Observable d = getData(args); d.map({ s -> if (s.equals(x)) { // do something } else { // do something else } });

Slide 16

Slide 16 text

OBSERVABLE API MORE FLEXIBLE One interface to rule them all. Client code treats all interactions with the API as ASYNCHRONOUS. The API implementation chooses whether something is BLOCKING or NON- BLOCKING and WHAT resources it uses.

Slide 17

Slide 17 text

HOW TO CREATE AN OBSERVABLE

Slide 18

Slide 18 text

Observable.create(new OnSubscribe() { @Override public void call(Subscriber subscriber) { try { subscriber.onNext("Hello"); subscriber.onCompleted(); } catch (Exception e) { subscriber.onError(e); } } })

Slide 19

Slide 19 text

ASYNC OBSERABLE WITH MULTIPLE VALUES

Slide 20

Slide 20 text

Observable getTopImages() { return Observable.create(new OnSubscribe() { @Override public void call(Subscriber subscriber) { try { for (id in imageIds) { Image i = …do network call… subscriber.onNext(i); } subscriber.onCompleted(); } catch (Exception e) { subscriber.onError(e); } } })

Slide 21

Slide 21 text

ASYNCHRONOUS OBSERVER

Slide 22

Slide 22 text

getTopImages().subscribe(new Observer() { void onNext(Image image) { println("Image: " + image.getImageId()); } void onError(Exception e) { println("Error"); e.printStackTrace(); } void onCompleted() { println("Completed"); } });

Slide 23

Slide 23 text

Transform: map, flatmap, reduce, scan Filter: take, skip, sample, takeWhile, filter Combine: concat, merge, zip, combineLatest,
 multicast, publish, cache, refCount Concurrency: observeOn, subscribeOn Error handling: onErrorReturn, onErrorResume OPERATORS COMPOSABLE FUNCTIONS AKA

Slide 24

Slide 24 text

MERGE COMBINING VIA

Slide 25

Slide 25 text

ZIP COMBINING VIA

Slide 26

Slide 26 text

ERRORS HANDLING

Slide 27

Slide 27 text

REAL WORLD EXAMPLE

Slide 28

Slide 28 text

this._episodeRepository.getEpisodeWithSegments(episodeId) .map(new Func1() { @Override public Episode call(Episode episode) { // Check if EPISODE segment is available… } }) .flatMap(new Func1>() { @Override public Observable call(final Episode episode) { // Write episode to database… } }) .subscribeOn(RxSchedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber() { // Add download to queue or notify error… });

Slide 29

Slide 29 text

MAP CHECK IF AUDIO SEGMENT IS AVAILABLE .map(new Func1() { @Override public Episode call(Episode episode) { // Check if EPISODE segment is available String downloadUrl = null; for (AudioSegment segment : episode.getSegments()) { if (segment.getType() == AudioSegment.Type.EPISODE && segment.getHttpUrl() != null) { downloadUrl = segment.getHttpUrl(); break; } }

Slide 30

Slide 30 text

MAP CHECK IF AUDIO SEGMENT IS AVAILABLE episode.getSegments()) { if (segment.getType() == AudioSegment.Type.EPISODE && segment.getHttpUrl() != null) { downloadUrl = segment.getHttpUrl(); break; } } if (downloadUrl == null) { throw new IllegalArgumentException(…); } // Update episode property episode.setOfflineUrl(downloadUrl); episode.setOfflineFilepath(_destinationFileForEpisode( episode.getEpisodeId()).getAbsolutePath()); episode.setOfflineAt(createdAt); episode.setOfflineStatus(Episode.OfflineStatus.WAITING); return episode; } })

Slide 31

Slide 31 text

FLATMAP WRITE EPISODE TO DATABASE WITH .flatMap(new Func1>() { @Override public Observable call(final Episode episode) { // Write episode to database return _offlineRepository .addOfflineEpisodeDatabase(ep) .map(new Func1() { @Override public Episode call(Boolean added) { return ep; } }); }})

Slide 32

Slide 32 text

SUBSCRIBE HANDLE ERROR OR SUCCESS ON .subscribe(new Subscriber() { @Override public void onError(Throwable e) { // Notify failure … } @Override public void onNext(Episode episode) { // Notify success and add to download queue … } });

Slide 33

Slide 33 text

Interactions with the API are ASYNCHRONOUS and DECLARATIVE API implementation controls CONCURRENCY BEHAVIOUR The only "rule" is: DON'T MUTATE STATE OUTSIDE OF FUNCTION LESSONS LEARNED TO SUM UP

Slide 34

Slide 34 text

ReactiveX: http://reactivex.io What does it means to be Reactive? https://www.youtube.com/watch? v=sTSQlYX5DU0 RxJava @ Github: https://github.com/ReactiveX/RxJava Observer Pattern: https://en.wikipedia.org/wiki/ Observer_pattern Marbles diagrams: http://rxmarbles.com/

Slide 35

Slide 35 text

THANK YOU