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
330
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
110
2000 katas later @CAS15
nhpatt
0
97
Métricas: lo bueno, lo feo y lo malo
nhpatt
0
240
Working Effectively with Legacy Code
nhpatt
0
410
Performance myths in android
nhpatt
2
280
How *not* to design an SDK
nhpatt
0
48
Angular2 @SC Toledo
nhpatt
0
57
Cambiar una empresa con juegos ágiles
nhpatt
0
250
Android M
nhpatt
0
72
Other Decks in Programming
See All in Programming
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
370
15年目のiOSアプリを1から作り直す技術
teakun
1
590
PostgreSQL を使った快適な go test 環境を求めて
otakakot
0
390
朝日新聞のデジタル版を支えるGoバックエンド ー価値ある情報をいち早く確実にお届けするために
junkiishida
1
350
AIとペアプロして処理時間を97%削減した話 #pyconshizu
kashewnuts
1
190
AI駆動開発の本音 〜Claude Code並列開発で見えたエンジニアの新しい役割〜
hisuzuya
4
460
Rで始めるML・LLM活用入門
wakamatsu_takumu
0
150
ベクトル検索のフィルタを用いた機械学習モデルとの統合 / python-meetup-fukuoka-06-vector-attr
monochromegane
2
240
エージェント開発初心者の僕がエージェントを作った話と今後やりたいこと
thasu0123
0
230
24時間止められないシステムを守る-医療ITにおけるランサムウェア対策の実際
koukimiura
2
180
要求定義・仕様記述・設計・検証の手引き - 理論から学ぶ明確で統一された成果物定義
orgachem
PRO
16
9.3k
20260228_JAWS_Beginner_Kansai
takuyay0ne
5
420
Featured
See All Featured
WENDY [Excerpt]
tessaabrams
9
36k
Chasing Engaging Ingredients in Design
codingconduct
0
130
ラッコキーワード サービス紹介資料
rakko
1
2.5M
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
330
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.3k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
0
170
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
1
140
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
240
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
5.3k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1k
HDC tutorial
michielstock
1
480
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
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