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

Intro to Functional Reactive Programming (Droid...

Juan Gomez
April 12, 2015

Intro to Functional Reactive Programming (Droidcon MTL 2015)

This talk will be an introduction to the ideas behind functional reactive programming and how you can move away from traditional synchronous state management with variables to asynchronous streams of data instead. You will learn how Rx (Reactive Extensions) Observables simplify concurrent code and let you write asynchronous, message based Android apps, in ways that are more elegant and a bit less error prone than traditional Android mechanisms.

We will also take a look at some Higher-order functions such as map(), flatmap(), filter() and reduce() that enable you to write simple, expressive and concise code to process Observables and solve problems in many common Android scenarios. These powerful yet easy to use abstractions will let you write asynchronous code in a more straightforward, declarative fashion; making your life as an Android developer a lot easier.

Juan Gomez

April 12, 2015
Tweet

More Decks by Juan Gomez

Other Decks in Technology

Transcript

  1. Intro Who am I? • Mobile Engineer at Netflix •

    Previously at Eventbrite and OneLouder Apps • Android & Python Developer
  2. Agenda • Brief introduction to Rx and why we want

    to use it. • Observables and useful operators to transform Observables. • Brief introduction to RxAndroid.
  3. Multithreading is hard! This is a lesson I seem to

    learn every few years: multithreading is hard.
 Once you think you now understand it and are an expert, you are heading soon to another painful lesson that multithreading is hard. - Dianne Hackborn April 2012
  4. What Is Functional Reactive Programming? • A style of programming

    based on two key ideas: continuous time-varying behaviors, and event-based reactivity. • Popularized by Erik Meijer when he created the Rx library for .NET while at Microsoft.
  5. Why Functional Reactive Programming • Writing concurrent programs correctly is

    difficult. • You can transform & compose asynchronous operations. • High-level abstractions • Standard error handling
  6. Rx Family • C#: Rx.NET • JavaScript: RxJS • RxJava

    (Java, Scala, Groovy, Clojure, Kotlin) • Ruby: Rx.rb • Python: RxPY • More at: http://reactivex.io/
  7. RxJava • It’s a JVM implementation of Reactive Extensions •

    Extends Observer pattern to support data/event and compose operators in abstract. • Started at Netflix • Supports Java 6+ & Android 2.3+ • Java 8 lambda support
  8. Observables event Iterable (pull) Observable (push) retrieve data T next()

    onNext(T) discover error throws Exception onError(Exception) complete !hasNext() onCompleted() It’s like the GoF Observer++
  9. RxJava on Java 7 aObservable.filter(new Func1<Integer, Boolean>() { public Boolean

    call(Integer n) { return n % 2 == 0; } }) .map(new Func1<Integer, Integer>() { public Integer call(Integer n) { return n * n; } }) .subscribe(new Action1<Integer>() { public void call(Integer n) { System.out.println(n); } });
  10. Retrolambda Retrolambda lets you take advantage of Java 8 features

    like lambda expressions and method references on Java 7 or lower. • Retrolambda • https://github.com/orfjackal/retrolambda • Gradle plugin • https://github.com/evant/gradle-retrolambda
  11. RxJava using Retrolambda aObservable.filter(n -> n % 2 == 0)

    .map(n -> n * n) .subscribe(System.out::println);
  12. Creating an Observable List<String> aList = ...; ob = Observable.create(subscriber

    -> { try { for (String s : aList) { if (subscriber.isUnsubscribed()) return; subscriber.onNext(s); } subscriber.onCompleted(); } catch (Exception e) { subscriber.onError(e); } });
  13. Creating an Observable • repeat( ) • range( ) •

    interval( ) • timer( ) • empty( ) • error( ) • More at: https://github.com/ReactiveX/RxJava/wiki/Creating- Observables
  14. Transforming Observables Observable.range(0, 5) .map(x -> toBinaryString(x*x)) .subscribe(s -> println(s),

    err -> err.printStackTrace(), () -> println("done")); 0 1 100 1001 10000 done
  15. Transforming Observables 1 2 2 3 3 3 Observable.range(1, 3)

    .flatMap(x -> Observable.just(x).repeat(x)) .subscribe(System.out::println);
  16. Filtering Observables 0 2 4 6 8 Observable.range(0, 10) .filter(x

    -> (x % 2) == 0) .subscribe(System.out::println);
  17. Filtering Observables • distinct( ) • first( ) • take(

    ) • skip( ) • elementAt( ) • sample( ) • more... • More at: https://github.com/ReactiveX/RxJava/wiki/Filtering-Observables
  18. Combining Observables a_A b_B c_C Observable<String> lower = Observable.from(new String[]{"a",

    "b", "c"}); Observable<String> upper = Observable.from(new String[]{"A", "B", "C"}); Observable.zip(lower, upper, Pair::create) .map(pair -> pair.first +"_" +pair.second) .subscribe(System.out::println);
  19. Threading • observeOn • specify on which Scheduler a Subscriber

    should observe the Observable • subscribeOn • specify which Scheduler an Observable should use when its subscription is invoked • https://github.com/ReactiveX/RxJava/wiki/ Scheduler
  20. Backpressure • Backpressure is the situation in which an Observable

    is emitting items more rapidly than an operator or subscriber can consume them. • RxJava offers a variety of strategies like throttling with which you can exercise flow control in order to alleviate the problems caused by backpressure. • https://github.com/ReactiveX/RxJava/wiki/Backpressure
  21. Hot and Cold Observables • A “cold” Observable waits to

    start emitting items until an observer subscribes, and so an observer can “observe” the whole sequence. • A “hot” Observable may begins emitting items as soon as it is created.
  22. RxAndroid • Android specific bindings for RxJava. • https://github.com/ReactiveX/RxAndroid •

    Scheduler on main UI thread or a given Android Handler thread. • AndroidSchedulers • HandlerThreadScheduler • Reactive components for common Android use cases and UI widgets • AndroidObservable • ViewObservable
  23. Android Example /* API */ Observable<String> getFromServer(String key); Observable<String> getFromDB(String

    key); /* Code */ ViewObservable.clicks(btnClick) .map(x -> "myid") .observeOn(Schedulers.io()) .flatMap(this::getFromDB) .flatMap(this::getFromServer) .observeOn(AndroidSchedulers.mainThread()) .subscribe(x -> Toast.makeText(context, x, LENGTH_LONG).show());
  24. Summary • Embrace Reactive and Functional Thinking • Manipulating Streams

    of Data simplifies who we think (and build) our programs. • RxJava is a powerful tool to improve your Android Code