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

Reactive programming on Android - why and how (Droidcon Krakow 2016)

Sasa Sekulic
December 08, 2016

Reactive programming on Android - why and how (Droidcon Krakow 2016)

Reactive is becoming more and more used on Android, but is it right for you? This presentation sheds some light on why reactive programming is becoming so popular and what are the pros and cons of using it. It also explores the library and framework options, possible architectures and compare it all to the normal Android framework.

Sasa Sekulic

December 08, 2016
Tweet

More Decks by Sasa Sekulic

Other Decks in Programming

Transcript

  1. Reactive programming on Android - why and how Sasa Sekulic

    co-author of the upcoming Manning book “Grokking Rx” (with Fabrizio Chignoli and Ivan Morgillo) developer of the UN-WFP ShareTheMeal app cofounder of Alter Ego Solutions @sasa_sekulic | www.alterego.solutions | Grokking Rx: http://bit.ly/grokking-rx
  2. UN WFP ShareTheMeal We provide food to schoolchildren in need

    - over 8 million meals! It costs only 35p to feed one child for a day. www.sharethemeal.org Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  3. Team #droidconPL Join the team by donating: http://bit.ly/2hn3xFT Rx on

    Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  4. Abridged evolution of OOP language evolution 1995 - Java, JavaScript,

    Delphi 2004 - Java 1.5: generics, futures 2011 - C++ 11: lambdas, futures & promises 2014 - C++ 14: generic lambdas 2014 - Java 1.8: lambdas, streams, CompletableFuture 2015 - EcmaScript 6: futures & promises 2017? - Java 1.9: Flow (with limited operators) MAINSTREAM OOP LANGUAGES: OLD, IMPROVING SLOWLY! Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  5. Declarative vs. imperative Imperative/procedural/OOP: - we use statements to change

    program state (data) -> we need to interpret the current state to get to new state Declarative/functional: - we evaluate functions (no previous state, no mutable data) Declarative/dataflow/reactive: - changes are propagated -> marries well with event-based systems (event-driven prog.) Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  6. What's missing in Java/Android? pt.1 Collections are strange: - why

    static Collections.sort() and not list.sort()? - why static Arrays.toArray()? Arrays.sort()? OOP much?! - why Iterator.hasNext() and not list.hasNext? - Gang of four Iterator is forward biased! Finally, in Java 8 we have list.forEach()! Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  7. What's missing in Java/Android? pt.2 Observing changes is non-standard: -

    Observable/Observer: exist since Java 1.0, but were never used anywhere; rudimentary GoF implementation - no Collection listeners/observers - Android uses listeners everywhere, in a non-standardized manner (add() vs set() vs method parameter) Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  8. What's missing in Java/Android? pt.3 Multithreading management is very basic:

    - AsyncTask: must be created/invoked from UI thread; cannot be repeated; must use custom executors for multithreading; no thread-switching (beyond UI/non-UI); no repeating, syncing or daisy-chaining helpers - Executors (pure Java): default Android executor is single- threaded; have to create your own executors, and manage them manually Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  9. What's missing in Java/Android? pt.4 Multithreading mgmt, cont'd - no

    easy way to synchronize nested asynchronous calls: - callbacks are not universal - composing is very manual (you have to write everything) - reuse of methods with callbacks is (almost) impossible https://gist.github.com/benjchristensen/4677544 Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  10. What's missing in Java/Android? pt.5 Multithreading mgmt, cont'd - Future/Promise

    don't solve the problem: - introduced in Java 1.5, but no support for syncing, grouping, composing; Future.get() is blocking https://gist.github.com/benjchristensen/4671081 - CompletableFuture with grouping and composing only in Java 8, but with very limited features; ignored in JDK; represents only one future value Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  11. What's missing in Java/Android? - conclusion PREMISE: Mobile devices are

    asynchronous by default (event-based UI, async communication, event-based sensors) PREMISE: Mobile devices now all have multi-core CPUs PROBLEM: Asynchronous, multithreaded event and data handling on Android is PITA! Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  12. Why Rx? - Pros - standardized multiplatform library for functional

    and reactive programming (not FRP! https://github.com/conal/talk-2015-essence-and- origins-of-frp) - universal event interface instead of custom listeners - asynchronous by default; but synchronization is easy - easier to do event-driven programming (event sourcing?) - simplified multithreading management - composable (made for data flows) with lots of operators! Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  13. Why Rx? - Cons - it's an external library: v1.2.0

    rx adds around 5k methods, 2.5k fields - uses more memory - but the data is immutable - complex flows and multithreading are still complex (but easier to control and implement) - lifecycle management - careful around Context references in Android (but that's always valid) - testing and debugging are tricky Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  14. Why Rx? - Benchmarking calls Benchmarking receiving n events with

    100ms delay https://github.com/ akarnokd/AgeraTest2 (Samsung S5 Neo, normal usage) Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  15. Why Rx? - Benchmarking calls Benchmarking receiving n events with

    100ms delay https://github.com/ akarnokd/AgeraTest2 (Samsung S5 neo, normal usage) Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  16. Why Rx? - Benchmarking apps https://github.com/alter-ego/RxJavaAndroidBenchmark/ https://nimbledroid.com/my_apps/solutions.alterego.stack overflow.norx.test https://nimbledroid.com/my_apps/solutions.alterego.stack overflow.test

    https://nimbledroid.com/my_apps/solutions.alterego.stack overflow.rx2.test App without RxJava: 31.3k methods, 3.66MB, search page loading 1.8s App w/RxJava 1.x: +5.5k (18%), +340kB (9%), page loading -0.3s (-16.6%) App w/RxJava 2.0 RC5: +9k (29%), +560kB (15%), loading -0.4s (-22%) max RAM use, max CPU, startup time etc = same Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  17. Alternatives to Rx - non-reactive solutions Combining an event bus

    library (Otto) with data flow library (Guava) - Guava has Iterable and ListenableFuture, and Otto has universal event management - adds 9k methods, 1k fields and 450kB MORE than Rx1! Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  18. Alternatives to Rx - non-reactive solutions, cont'd Otto & Guava

    - bigger than Rx - have to write interfaces between libraries - data flows still synchronous - no threading management - missing advanced operators - Otto is deprecated in favour of RxJava! Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  19. Alternatives to Rx - other reactive libraries • Project Reactor

    (http://projectreactor.io/) - looks good, but slower than RxJava and needs Java 8; no Android support http://akarnokd.blogspot.hu/2015/10/comparison -of-reactive-streams.html • Java 9 Flow - just basic implementation of RS 1.0; also Java 9 • Google Agera - slow, buggy, untested, non-standard; supports Android http://akarnokd.blogspot.hu/2016/04/google- agera-vs-reactivex.html Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  20. Alternatives to Rx - DIY How about standard Java/Android with

    your own implementation? - if you're an expert reactive/functional developer with lots of time and lots of friends willing to write docs, debug, contribute and test (NIH fallacy) - Java 8 Streams are quick, but they're not reactive! (http://akarnokd.blogspot.hu/2015/10/comparison- of-reactive-streams.html) - also, Java 8! Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  21. Why Rx? - Costs Distinguish between absolute costs (compared to

    internal Android libraries and doing everything manually) and relative costs (compared to other libraries) - other libraries are slower and/or less compatible with Android - unless you have substantial time, expertise and resources at your disposal, DO NOT WRITE ANOTHER REACTIVE LIBRARY! - sync is always quicker than async, but it doesn't matter for most cases! Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  22. Why Rx? - sync vs async Rx on Android |

    @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx http://akarnokd.blogspot.hu/2015/10/comparison-of-reactive-streams.html
  23. Why Rx? - Review - costs are as with any

    other library - supported by lots of other libraries (Retrofit...) - well tested, well documented - helps you use Android hardware better - de facto standard for reactive programming in Java/Android REACTIVE PROGRAMMING WILL MAKE YOU THINK DIFFERENTLY! IN MOST CASES, USING RXJAVA WILL HELP IMPROVE THE APP SPEED Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  24. Rx and app/view architecture - indifferent, do what you want!

    - on Android, in regards to view architecture marries well with MVP, and marries even better with MVVM (http://www.slideshare.net/FlorinaMuntenescu/mvvm-and-rxjava-the- perfect-mix-61526418) Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  25. Rx 2.x vs Rx 1.x? - supports Reactive Streams interface

    - JVM reactive standard https://github.com/ReactiveX/RxJava/wiki/Reactive-Streams - BUT Reactive Streams != Rx - explicit distinction between backpressure support and no backpressure support (Observable vs Flowable, Subjects vs Processors) - Observable.create() is now safe - no passing nulls as values! - Subscriptions are now Disposables (like in .Net) Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  26. Rx 2.x vs Rx 1.x? - cont'd - Subscriptions are

    not returned as values (as .subscribe() result) but passed as callback arguments (onSubscribe()) - easier to test - there's test()! - all in all, it's more optimized! FOR MORE DETAILS SEE https://github.com/ReactiveX/RxJava/wiki/What's- different-in-2.0 Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx
  27. Rx 2.x & Rx 1.x For rx 1.x <> rx

    2.x interop: https://github.com/akarnokd/RxJava2Interop Get ready: https://speakerdeck.com/jakewharton/looking-ahead-to- rxjava-2-droidcon-nyc-2016 Final release was on Oct 29, 2016! Rx on Android | @sasa_sekulic | #GrokkingRx | http://bit.ly/grokking-rx