Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to RxJava for Android

Dcafc93100ece4c0582543b020a63ec8?s=47 Esa Firman
October 23, 2015

Introduction to RxJava for Android

Dcafc93100ece4c0582543b020a63ec8?s=128

Esa Firman

October 23, 2015
Tweet

Transcript

  1. Introduction to RxJava for Android Esa Firman

  2. 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
  3. The Problem How to deal with execution context ?

  4. 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();
  5. Threads Pros: - Simple Cons: - Hard way to deliver

    results in UI thread - Pyramid of Doom
  6. AsyncTask new AsyncTask<Void, Integer, String>(){ @Override protected String doInBackground(Void... params)

    { return doHeavyTask(); } @Override protected void onPostExecute(String s) { showResult(s); } }.execute();
  7. AsyncTask Pros: - Deal with main thread Cons: - Hard

    way to handling error - Not bound to activity/fragment lifecycle - Not composable - Nested AsyncTask - “Antek Async”
  8. Why Rx? - Because multithreading is hard - Execution context

    - Powerful operators - Composable - No Callback Hell - Etc ...
  9. 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.
  10. The Basic Observables often don't start emitting items until someone

    explicitly subscribes to them
  11. Enough talk, let’s see some code ...

  12. Hello World public Observable<String> getStrings() { return Observable.create(new Observable.OnSubscribe<String>() {

    @Override public void call(Subscriber<? super String> subscriber) { try { subscriber.onNext("Hello, World"); subscriber.onCompleted(); } catch (Exception ex) { subscriber.onError(ex); } } }); }
  13. 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); } };
  14. Observable<String> myObservable = Observable.just("Hello, world!"); Action1<String> onNextAction = new Action1<>()

    { @Override public void call(String s) { System.out.println(s); } }; myObservable.subscribe(onNextAction); // Outputs "Hello, world!" Simpler Code
  15. Simplest* Code - Using Lambda Observable.just("Hello, World").subscribe(System.out::println); *AFAIK

  16. 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
  17. Operators

  18. 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
  19. None
  20. 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
  21. 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
  22. None
  23. Map Observable.from(Arrays.asList("Esa", "Esa", "Esa")) .map(s -> s + " ganteng")

    .subscribe(System.out::println); // print Esa ganteng 3 times
  24. None
  25. FlatMap Observable.just( Arrays.asList("Tiramisu", "Black Forest", "Black Mamba")) .flatMap(Observable::from) .map(String::length) .subscribe(System.out::print);

    // print 8,11,12
  26. Confused? Getting map/flatMap/compose mixed up? Think types: map : T

    -> R flatMap : T -> Observable<R> compose : Observable<T> -> Observable<R> #ProTips
  27. Retrofit Integration @GET("mobile_detail_calc_halte_trans.php") Observable<List<HalteDetail>> getHalteDetails(@Query("coridor") String coridor); mApiService.getHalteDetails(halte.getCoridor()) .observeOn(AndroidSchedulers.mainThread()) .doOnTerminate(this::resetUILoading)

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

    (comments != null) mCommentAdapter.pushData(comments); });
  29. More Samples Observable<Bitmap> 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
  30. More Examples public Observable<List<Area>> getAreas() { Observable<List<Area>> network = mApiService.getArea()

    .observeOn(AndroidSchedulers.mainThread()) .doOnNext(areas -> saveAreas(areas)); Observable<List<Area>> cache = getAreasFromLocal(); return Observable.concat(cache, network).first(areas -> areas != null); }
  31. 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); });
  32. FAQ 1. Should we still use Thread and AsyncTask? 2.

    Where to start?
  33. 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
  34. 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
  35. Questions?