Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
RxJava in practice
Search
Javier Gamarra
November 30, 2015
Programming
1
320
RxJava in practice
Slides for a workshop about RxJava & RxAndroid delivered at the Codemotion 2015.
Javier Gamarra
November 30, 2015
Tweet
Share
More Decks by Javier Gamarra
See All by Javier Gamarra
2000 katas later @cylicon
nhpatt
0
100
2000 katas later @CAS15
nhpatt
0
95
Métricas: lo bueno, lo feo y lo malo
nhpatt
0
230
Working Effectively with Legacy Code
nhpatt
0
390
Performance myths in android
nhpatt
2
260
How *not* to design an SDK
nhpatt
0
48
Angular2 @SC Toledo
nhpatt
0
55
Cambiar una empresa con juegos ágiles
nhpatt
0
240
Android M
nhpatt
0
68
Other Decks in Programming
See All in Programming
High-Level Programming Languages in AI Era -Human Thought and Mind-
hayat01sh1da
PRO
0
880
PicoRuby on Rails
makicamel
2
140
Azure AI Foundryではじめてのマルチエージェントワークフロー
seosoft
0
200
LT 2025-06-30: プロダクトエンジニアの役割
yamamotok
0
870
Quand Symfony, ApiPlatform, OpenAI et LangChain s'allient pour exploiter vos PDF : de la théorie à la production…
ahmedbhs123
0
220
PHPでWebSocketサーバーを実装しよう2025
kubotak
0
320
たった 1 枚の PHP ファイルで実装する MCP サーバ / MCP Server with Vanilla PHP
okashoi
1
300
The Niche of CDK Grant オブジェクトって何者?/the-niche-of-cdk-what-isgrant-object
hassaku63
1
610
可変変数との向き合い方 $$変数名が踊り出す$$ / php conference Variable variables
gunji
0
180
リバースエンジニアリング新時代へ! GhidraとClaude DesktopをMCPで繋ぐ/findy202507
tkmru
3
960
The Evolution of Enterprise Java with Jakarta EE 11 and Beyond
ivargrimstad
0
260
顧客の画像データをテラバイト単位で配信する 画像サーバを WebP にした際に起こった課題と その対応策 ~継続的な取り組みを添えて~
takutakahashi
4
1.3k
Featured
See All Featured
The Pragmatic Product Professional
lauravandoore
35
6.7k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
21k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
35
2.4k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
60k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
8
700
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
47
9.6k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
BBQ
matthewcrist
89
9.7k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
830
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Transcript
MADRID · NOV 27-28 · 2015 RxJava in practice Javier
Gamarra
MADRID · NOV 27-28 · 2015 http://kcy.me/29crj (slides) & http://kcy.me/296bu
(commits)
MADRID · NOV 27-28 · 2015 Environment Eclipse | Android
Studio (RxAndroid) RxJava.jar [Java 8] || [Retrolambda] :P
MADRID · NOV 27-28 · 2015 Environment Android Studio: compile
'io.reactivex:rxandroid:1.0.1' compile 'io.reactivex:rxjava:1.0.16' Eclipse: • Copy jars to lib/ and add jar in project
MADRID · NOV 27-28 · 2015 Github • http://kcy.me/296bu •
koans • código • commit a commit • Podéis preguntarme en cualquier momento
MADRID · NOV 27-28 · 2015 Who? Javier Gamarra /
@nhpatt @liferay @cyliconvalley / @agilespain
MADRID · NOV 27-28 · 2015 Ask! Please? Pretty please?
Please pretty please with sugar on top?
MADRID · NOV 27-28 · 2015 Background?
MADRID · NOV 27-28 · 2015 Why?
MADRID · NOV 27-28 · 2015 Why? (in java) multithreading
is hard futures are complicated callbacks are hell
MADRID · NOV 27-28 · 2015 Rx comes to the
rescue!
MADRID · NOV 27-28 · 2015 a library to represent
any operation as an asynchronous data stream on any thread, declaratively composed, and consumed by multiple objects
MADRID · NOV 27-28 · 2015 a library
MADRID · NOV 27-28 · 2015 A library? Extensions to
.NET framework Netflix
MADRID · NOV 27-28 · 2015 Libraries are tools If
all you have is a hammer, everything looks like a nail
MADRID · NOV 27-28 · 2015 a library to model
Observables & Subscribers
MADRID · NOV 27-28 · 2015 Observables and Subscribers An
Observable emits items. A Subscriber consumes those items.
MADRID · NOV 27-28 · 2015 Observer pattern?
MADRID · NOV 27-28 · 2015 My very first observable
Observable<String> myObs = Observable. create(new Observable. OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { subscriber.onNext( "Hi!"); subscriber.onCompleted(); } });
MADRID · NOV 27-28 · 2015 My very first subscriber
Subscriber<String> mySubs = new Subscriber<String>() { @Override public void onCompleted() { } @Override public void onError(Throwable throwable) { } @Override public void onNext(String s) { System. out.println(s); } };
MADRID · NOV 27-28 · 2015 My very first subscription
myObs.subscribe(mySubs);
MADRID · NOV 27-28 · 2015 A bit verbose... Let’s
simplify with Java8 and RxJava • lamdbas • Observable.just • .subscribe()
MADRID · NOV 27-28 · 2015 That’s better... Observable .just("Hi!")
.subscribe(System.out::println);
MADRID · NOV 27-28 · 2015 Why? More than the
observer pattern • Observables only emit when someone listening • OnFinished • OnError
MADRID · NOV 27-28 · 2015 Let’s use those differences
subscribe admits 3 parameters • OnNext • OnFinished • OnError
MADRID · NOV 27-28 · 2015 You said “items” Observable.from
admits a list of elements
MADRID · NOV 27-28 · 2015 Ok, let’s recap… Iterators?
MADRID · NOV 27-28 · 2015 Iterators? • Iterators are
pull and synchronous • Subscribers are push and asynchronous
MADRID · NOV 27-28 · 2015 to represent any operation
as an “asynchronous data stream”
MADRID · NOV 27-28 · 2015 Everything is a stream
MADRID · NOV 27-28 · 2015 Everything is a stream
We can model everything as a stream
MADRID · NOV 27-28 · 2015 Everything is a stream
A network call is also a stream Like using retrofit with this API
MADRID · NOV 27-28 · 2015 “declaratively composed”
MADRID · NOV 27-28 · 2015 Operators
MADRID · NOV 27-28 · 2015 Operators Transform a stream
rxmarbles and android app
MADRID · NOV 27-28 · 2015 Operators Map
MADRID · NOV 27-28 · 2015 Map List<String> severalThings =
Arrays.asList("1", "2"); Observable.from(severalThings) .map((s) -> “Element “ + s) .subscribe(System.out::println);
MADRID · NOV 27-28 · 2015 Map We can return
another type: List<String> severalThings = Arrays.asList("1", "2"); Observable.from(severalThings) .map(Integer::valueOf) .subscribe(System.out::println);
MADRID · NOV 27-28 · 2015 Map Let’s do the
same with our repos… And… I can’t because we return a List And using Observable.from… NOP
MADRID · NOV 27-28 · 2015 Flatmap Flatmap Obs ->
elements
MADRID · NOV 27-28 · 2015 Flatmap service.listRepos("nhpatt") .flatMap(Observable::from) .map(Repo::getName)
.map((s) -> s.replace("-", " ")) .subscribe(System.out::println);
MADRID · NOV 27-28 · 2015 Flatmap Concatmap -> ordered
flatmap
MADRID · NOV 27-28 · 2015 Filter service.listRepos("nhpatt") .flatMap(Observable::from) .map(Repo::getName)
.map((s) -> s.replace("-", " ")) .filter((s) -> s.startsWith("Android")) .subscribe(System.out::println);
MADRID · NOV 27-28 · 2015 Scan & old code
service.listRepos("nhpatt") .flatMap(Observable::from) .map(Repo::getName) .map((s) -> s.replace("-", " ")) .filter((s) -> s.startsWith("Android")) .take(2) .map(String::length) .scan((x, y) -> x * y) .subscribe(System.out::println);
MADRID · NOV 27-28 · 2015 Scan & old code
(l) -> { int result = 0; int i = 0; int oldLength = 1; for (Repo repo : l) { String name = repo.getName(); String replacedName = name.replace( "-", " "); if (replacedName.startsWith( "Android") && i < 2) { result = replacedName.length() * oldLength; oldLength = result; System.out.println(result); i++; } } return result;
MADRID · NOV 27-28 · 2015 Operators • merge •
flatMap • zip Nice things™ : parallel jobs!
MADRID · NOV 27-28 · 2015 Zipping requests Observable<Repo> repo
= service.listRepos("nhpatt") .flatMap(Observable::from) .take(1); Observable<Commit> commit = service.listCommits("nhpatt", "Android") .flatMap(Observable::from) .take(1); Observable.zip(repo, commit, this::updateCommit).subscribe (repo1 -> { System.out.println(repo1.getCommit().getUrl()); });
MADRID · NOV 27-28 · 2015 Operators Amazing documentation •
Async • Blocking • Combining • Conditional • Error handling • Filtering • Mathematical • Creation • String • Transforming • Utility
MADRID · NOV 27-28 · 2015 Subscribers are asynchronous? No,
not really
MADRID · NOV 27-28 · 2015 “on any thread”
MADRID · NOV 27-28 · 2015 Schedulers!
MADRID · NOV 27-28 · 2015 Schedulers I define an
API declaratively and later in the implementation run it: asynchronously or in a separate Thread or in a Threadpool or synchronously ...
MADRID · NOV 27-28 · 2015 Schedulers .subscribeOn(Schedulers...) .observeOn(Schedulers...) •
io • computation • newThread • trampoline • test
MADRID · NOV 27-28 · 2015 Schedulers service.listRepos("nhpatt") .subscribeOn(Schedulers.immediate()) .observeOn(Schedulers.immediate())
.subscribe(System.out::println);
MADRID · NOV 27-28 · 2015 Schedulers RxJava operators have
default threads Interval?
MADRID · NOV 27-28 · 2015 Use cases?
MADRID · NOV 27-28 · 2015 Use cases • Autocomplete
with debounce | sample… • Accumulate calls with buffer... • Polling with timeout | window… • Form Validation with combineLatest… • Retrieve data fast from cache | network call with concat | merge… • Button click with delay, listen on other thread
MADRID · NOV 27-28 · 2015 Android?
MADRID · NOV 27-28 · 2015 Why?
MADRID · NOV 27-28 · 2015 Why? (in android) Main/UI
thread and background problem • Can’t do heavy tasks on UI • Can’t update view on background • AsyncTasks are bad • Handlers can leak
MADRID · NOV 27-28 · 2015 How RxAndroid helps?
MADRID · NOV 27-28 · 2015 Android schedulers service.listRepos("nhpatt") .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .subscribe(newRepos -> { repos.addAll(newRepos); adapter.notifyDataSetChanged(); });
MADRID · NOV 27-28 · 2015 Orientation Problem Orientation Problem
• onCreate gets called again • state is lost
MADRID · NOV 27-28 · 2015 Orientation Problem Programmer’s job:
• Store/Restore state • Restore view • Call again the user task? • Wait until it finishes?
MADRID · NOV 27-28 · 2015 How RxAndroid helps?
MADRID · NOV 27-28 · 2015 Orientation Problem Observable is
easy to persist (retain | singleton) Observable can continue (cache and retry) RxLifecycle
MADRID · NOV 27-28 · 2015 Orientation Problem Observable<List<Repo>> github
= RetrofitService. getGithub() .listRepos("nhpatt") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .cache();
MADRID · NOV 27-28 · 2015 More Android Lifecycle (RxLifecyle)
Views (RxBinding)
MADRID · NOV 27-28 · 2015 But...
MADRID · NOV 27-28 · 2015 But... Subscriptions leak memory
:’( We have to call to unsubscribe (CompositeSubscription helps) And don’t include references to the object/activity
MADRID · NOV 27-28 · 2015 Easy to unsubscribe @Override
protected void onStop() { super.onStop(); subscription.unsubscribe(); } .isUnsubscribed() :(
MADRID · NOV 27-28 · 2015 Let’s recap
MADRID · NOV 27-28 · 2015 a library to represent
any operation as an asynchronous data stream on any thread, declaratively composed, and consumed by multiple objects
MADRID · NOV 27-28 · 2015 a library to represent
any operation as an observable on any thread, declaratively composed, and consumed by multiple objects
MADRID · NOV 27-28 · 2015 a library to represent
any operation as an observable with schedulers declaratively composed, and consumed by multiple objects
MADRID · NOV 27-28 · 2015 a library to represent
any operation as an observable with schedulers and operators and consumed by multiple objects
MADRID · NOV 27-28 · 2015 a library to represent
any operation as an observable with schedulers and operators listened by subscribers
MADRID · NOV 27-28 · 2015 But...
MADRID · NOV 27-28 · 2015 But... • Learning curve
• Hard to debug (Frodo library) • Backpressure
MADRID · NOV 27-28 · 2015 Questions?
MADRID · NOV 27-28 · 2015 Where to know more...
• reactivex.io (amazing docs) • RxJava wiki • Dan Lew • Use cases
MADRID · NOV 27-28 · 2015 Where to know more...
nhpatt (twitter | github | email | slack) I’ll do anything for good votes
MADRID · NOV 27-28 · 2015 Feedback Click here :P
MADRID · NOV 27-28 · 2015 RxJava in practice Javier
Gamarra
MADRID · NOV 27-28 · 2015 Other interesting operators...
MADRID · NOV 27-28 · 2015 Take service.listRepos("nhpatt") .flatMap(Observable::from) .map(Repo::getName)
.map((s) -> s.replace("-", " ")) .filter((s) -> s.startsWith("Android")) .take(2) .subscribe(System.out::println);
MADRID · NOV 27-28 · 2015 Operators distinctUntilChanged compose
MADRID · NOV 27-28 · 2015 Errors?
MADRID · NOV 27-28 · 2015 onError() is called if
an Exception is thrown at any time (this is cool) The operators don't have to handle the Exception No more callbacks Errors
MADRID · NOV 27-28 · 2015 Errors And we can
customize the flow: onErrorResumeNext onErrorReturn retry ...
MADRID · NOV 27-28 · 2015 Why this is useful?
MADRID · NOV 27-28 · 2015 Why this is useful?
Observables and subscribers can do anything
MADRID · NOV 27-28 · 2015 Why this is useful?
Observable a database query Subscriber displaying results on the screen
MADRID · NOV 27-28 · 2015 Why this is useful?
Observable a click on the screen Subscriber reacting to it
MADRID · NOV 27-28 · 2015 Why this is useful?
Observable a stream of bytes from the internet Subscriber write them to disk
MADRID · NOV 27-28 · 2015 Why this is useful?
Observable and Subscriber are independent of the transformations
MADRID · NOV 27-28 · 2015 Why this is useful?
I can compose/chain any map/filter calls I want Only matters the return type
MADRID · NOV 27-28 · 2015 Side effects?
MADRID · NOV 27-28 · 2015 Side effects doOn methods:
• doOnNext() for debugging • doOnError() for error handling • doOnNext() to save/cache results
MADRID · NOV 27-28 · 2015 Side effects Observable someObservable
= Observable .from(Arrays.asList(new Integer[]{2, 7, 11})) .doOnNext(System.out::println) .filter(prime -> prime % 2 == 0) .doOnNext(System.out::println) .count() .doOnNext(System.out::println) .map( number -> String.format(“Contains %d elements”, number) );
MADRID · NOV 27-28 · 2015 Side effects flatMap(id ->
service.get() .doOnError(t -> { // report problem to UI }) .onErrorResumeNext(Observable.empty()))
MADRID · NOV 27-28 · 2015 Cold & Hot
MADRID · NOV 27-28 · 2015 Cold & Hot Observables
only emit when someone listening? Cold observables only emit when subscribed But hot observables emit instantly
MADRID · NOV 27-28 · 2015 Cold & Hot You
can convert between both states • “Hot -> cold” using defer() or merge(), zip()... • “Cold -> Hot” using publish() & connect()
MADRID · NOV 27-28 · 2015 Cold & Hot publish
& connect? “like transactions” Assume everything is cold
MADRID · NOV 27-28 · 2015 Testing?
MADRID · NOV 27-28 · 2015 More cool things? •
testscheduler • toIterator() • Obs.error(), Obs.empty()
MADRID · NOV 27-28 · 2015 Subjects
MADRID · NOV 27-28 · 2015 Subjects Both observable &
observer
MADRID · NOV 27-28 · 2015 Subjects AsyncSubject -> takeLast(1)
PublishSubject -> publish() ReplaySubject -> replay()/cache() BehaviorSubject -> replay(1)/cache(1)
MADRID · NOV 27-28 · 2015 RxJava in practice Javier
Gamarra