Slide 1

Slide 1 text

Introduction to RxJava for Android Esa Firman

Slide 2

Slide 2 text

What is RxJava? RxJava is a Java VM implementation of ReactiveX (Reactive Extensions): a library for composing asynchronous and event-based programs by using observable sequences See also: 2 minutes introduction to Rx https://medium.com/@andrestaltz/2-minute-introduction-to-rx-24c8ca793877#.rwup8ee0s

Slide 3

Slide 3 text

The Problem How to deal with execution context ?

Slide 4

Slide 4 text

Threads Handler handler = new Handler(Looper.getMainLooper()); new Thread(){ @Override public void run() { final String result = doHeavyTask(); handler.post(new Runnable() { // or runUIThread on Activity @Override public void run() { showResult(result); } }); } }.start();

Slide 5

Slide 5 text

Threads Pros: - Simple Cons: - Hard way to deliver results in UI thread - Pyramid of Doom

Slide 6

Slide 6 text

AsyncTask new AsyncTask(){ @Override protected String doInBackground(Void... params) { return doHeavyTask(); } @Override protected void onPostExecute(String s) { showResult(s); } }.execute();

Slide 7

Slide 7 text

AsyncTask Pros: - Deal with main thread Cons: - Hard way to handling error - Not bound to activity/fragment lifecycle - Not composable - Nested AsyncTask - “Antek Async”

Slide 8

Slide 8 text

Why Rx? - Because multithreading is hard - Execution context - Powerful operators - Composable - No Callback Hell - Etc ...

Slide 9

Slide 9 text

The Basic The basic building blocks of reactive code are Observables and Subscribers. An Observable emits items; a Subscriber consumes those items. The smallest building block is actually an Observer, but in practice you are most often using Subscriber because that's how you hook up to Observables.

Slide 10

Slide 10 text

The Basic Observables often don't start emitting items until someone explicitly subscribes to them

Slide 11

Slide 11 text

Enough talk, let’s see some code ...

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

Hello World getStrings().subscribe(new Subscriber(){ @Override public void onCompleted() { // no - op } @Override public void onError(Throwable e) { e.printStackTrace(); } @Override public void onNext(String s) { System.out.println(s); } };

Slide 14

Slide 14 text

Observable myObservable = Observable.just("Hello, world!"); Action1 onNextAction = new Action1<>() { @Override public void call(String s) { System.out.println(s); } }; myObservable.subscribe(onNextAction); // Outputs "Hello, world!" Simpler Code

Slide 15

Slide 15 text

Simplest* Code - Using Lambda Observable.just("Hello, World").subscribe(System.out::println); *AFAIK

Slide 16

Slide 16 text

Observable Creation Observable.create(Observable.onSubscribe) from( ) — convert an Iterable or a Future or single value into an Observable repeat( ) — create an Observable that emits a particular item or sequence of items repeatedly timer( ) — create an Observable that emits a single item after a given delay empty( ) — create an Observable that emits nothing and then completes error( ) — create an Observable that emits nothing and then signals an error never( ) — create an Observable that emits nothing at all

Slide 17

Slide 17 text

Operators

Slide 18

Slide 18 text

Filtering Operators - filter( ) — filter items emitted by an Observable - takeLast( ) — only emit the last n items emitted by an Observable - takeLastBuffer( ) — emit the last n items emitted by an Observable, as a single list item - skip( ) — ignore the first n items emitted by an Observable - take( ) — emit only the first n items emitted by an Observable - first( ) — emit only the first item emitted by an Observable, or the first item that meets some condition - elementAt( ) — emit item n emitted by the source Observable - timeout( ) — emit items from a source Observable, but issue an exception if no item is emitted in a specified timespan - distinct( ) — suppress duplicate items emitted by the source Observable

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

Filter Observable.just("Esa", "Ganteng", "Jelek") .filter(s -> !s.equalsIgnoreCase("jelek")) .buffer(2) .subscribe(strings -> { print(strings.get(0) + “ “ + strings.get(1)); }); // print Esa Ganteng

Slide 21

Slide 21 text

Transformation Operators - map( ) — transform the items emitted by an Observable by applying a function to each of them - flatMap( ) — transform the items emitted by an Observable into Observables, then flatten this into a single Observable - scan( ) — apply a function to each item emitted by an Observable, sequentially, and emit each successive value - groupBy( ) and groupByUntil( ) — divide an Observable into a set of Observables that emit groups of items from the original Observable, organized by key - buffer( ) — periodically gather items from an Observable into bundles and emit these bundles rather than emitting the items one at a time - window( ) — periodically subdivide items from an Observable into Observable windows and emit these windows rather than emitting the items one at a time

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

Map Observable.from(Arrays.asList("Esa", "Esa", "Esa")) .map(s -> s + " ganteng") .subscribe(System.out::println); // print Esa ganteng 3 times

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

FlatMap Observable.just( Arrays.asList("Tiramisu", "Black Forest", "Black Mamba")) .flatMap(Observable::from) .map(String::length) .subscribe(System.out::print); // print 8,11,12

Slide 26

Slide 26 text

Confused? Getting map/flatMap/compose mixed up? Think types: map : T -> R flatMap : T -> Observable compose : Observable -> Observable #ProTips

Slide 27

Slide 27 text

Retrofit Integration @GET("mobile_detail_calc_halte_trans.php") Observable> getHalteDetails(@Query("coridor") String coridor); mApiService.getHalteDetails(halte.getCoridor()) .observeOn(AndroidSchedulers.mainThread()) .doOnTerminate(this::resetUILoading) .subscribe(halteDetails -> { if (halteDetails != null) { setMarker(halteDetails); } });

Slide 28

Slide 28 text

More Examples mApiService.getCommentList() .compose(bindToLifecycle()) .compose(applyApiCall()) .doOnTerminate(this::stopLoading) .subscribe(comments -> { if (comments != null) mCommentAdapter.pushData(comments); });

Slide 29

Slide 29 text

More Samples Observable imageObservable = Observable.create(observer -> { Bitmap bm = downloadBitmap(); return bm; }); imageObservable.subscribe(image -> loadToImageView(image)); // blocking the UI thread imageObservable .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(image -> loadToImageView(image)); // non blocking but also execute loadToImageView on UI Thread

Slide 30

Slide 30 text

More Examples public Observable> getAreas() { Observable> network = mApiService.getArea() .observeOn(AndroidSchedulers.mainThread()) .doOnNext(areas -> saveAreas(areas)); Observable> cache = getAreasFromLocal(); return Observable.concat(cache, network).first(areas -> areas != null); }

Slide 31

Slide 31 text

More Examples (Again) public void onLocationChanged(Location location) { onLocationChanged.onNext(location); } mGmsLocationManager.onLocationChanged .throttleLast(10, TimeUnit.SECONDS) .observeOn(AndroidSchedulers.mainThread()) .subscribe(location -> { mPrensenter.updateMyLocation(location); });

Slide 32

Slide 32 text

FAQ 1. Should we still use Thread and AsyncTask? 2. Where to start?

Slide 33

Slide 33 text

Third Party Implementation - Android ReactiveLocation https://github.com/mcharmas/Android-ReactiveLocation - RxPermissions https://github.com/tbruyelle/RxPermissions - RxBinding https://github.com/JakeWharton/RxBinding - SQLBrite https://github.com/square/sqlbrite - RxLifeCycle https://github.com/trello/RxLifecycle

Slide 34

Slide 34 text

Links - http://slides.com/yaroslavheriatovych/frponandroid - https://github.com/Netflix/RxJava/ - https://github.com/orfjackal/retrolambda - https://github.com/evant/gradle-retrolambda - http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation.html - https://github.com/Netflix/RxJava/wiki

Slide 35

Slide 35 text

Questions?