SlideShare a Scribd company logo
Reactive Programming
RxJava for android
Richard Radics
Lead Android Developer
We are Supercharge
We experiment, we move fast,
we make it happen
At Supercharge we build high-impact mobile products making life easier for millions of users. Creating
stunning experiences can only happen if you stretch yourself. To supercharge means to go that extra mile.
Telekom RO
The official self-care application of the Deutsche Telekom was completed within 14 weeks on iOS and Android. The application amassed nearly 1M downloads to
date in the first launch country, Romania. The core functionality of the app became the model for DT’s European-wide self-care application and is expected to be
rolled out in 8-10 countries in 2016. Supercharge currently maintains the core codebase and 3 countries.
Jenius
Indonesia’s fastest growing financial institute’s new app is an exciting example of modern mobile banking solutions. BTPN has over 100 million customer in the South East Asian region:
their new app offers unique User Experience for all of them through its innovative functionality. Just to name a few interesting features: bill splitting enables coworkers to easily divide
their lunch expenses, with the Cashtag function users can easily transfer money to “#someone” with the use of tagging. We are especially proud that our extremely effectively
workflows and processes made it possible to reach the UAT phase of an app consisting of over 170 screens within 3 months of development (on two mobile platforms simultaneously).
The application has been developed in cooperation with Misys.
Let’s start…
Supercharge 6
Reactive Programming
Supercharge 7
Erik Meijer – Rx .Net Ben Christensen - RxJava
ReactiveX
•  Data Flow
•  Observer Pattern
•  Push vs Pull
Supercharge 8
Functional Reactive Programming (RxJava) on Android
Functional Reactive Programming (RxJava) on Android
Creating Observables
From
Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};!
public Observable<Integer> fromExample() {!
return Observable.from(testIntData);!
}!
!
!
Converts an iterable into an observable that emits all items
in the iterable and calls onComplete. The resulting observable
works synchronously.
Supercharge 12
From
Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};!
public Observable<Integer> fromExample() {!
return Observable.from(testIntData);!
}!
!
!
Converts an iterable into an observable that emits all items
in the iterable and calls onComplete. The resulting observable
works synchronously.
Supercharge 13
Just
Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};!
public Observable<Integer[]> justExample() {!
return Observable.just(testIntData);!
}!
Emit the object in onNext and calls onComplete.
Does not try to iterate the object.
Supercharge 14
Just
Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};!
public Observable<Integer[]> justExample() {!
return Observable.just(testIntData);!
}!
Emit the object in onNext and calls onComplete.
Does not try to iterate the object.
Supercharge 15
Create
Observable<Integer> getDataAsync(int i) {!
return getDataSync(i).subscribeOn(Schedulers.io());!
}!
Observable<Integer> getDataSync(int i) {!
return Observable.create(subscriber -> {!
try { !
Thread.sleep(rand(100, 500)); !
subscriber.onNext(i);!
subscriber.onCompleted();!
}catch (Exception e){!
subscriber.onError(e);!
}!
});!
}!
Supercharge 16
Create
Observable<Integer> getDataAsync(int i) {!
return getDataSync(i).subscribeOn(Schedulers.io());!
}!
Observable<Integer> getDataSync(int i) {!
return Observable.create(subscriber -> {!
try { !
Thread.sleep(rand(100, 500)); !
subscriber.onNext(i);!
subscriber.onCompleted();!
}catch (Exception e){!
subscriber.onError(e);!
}!
});!
}
Supercharge 17
Operators
Filter
Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};!
Observable!
.from(testIntData)!
.filter(integer -> integer % 2 == 0)!
.subscribe(System.out::println);!
Supercharge 19
Filter
Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};!
Observable!
.from(testIntData)!
.filter(integer -> integer % 2 == 0)!
.subscribe(System.out::println);!
// 2
// 4
Supercharge 20
Take first N values
Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};!
Observable!
.from(testIntData)!
.take(2)!
.subscribe(System.out::println);!
!
!
Supercharge 21
Take first N values
Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};!
Observable!
.from(testIntData)!
.take(2)!
.subscribe(System.out::println);!
// 1
// 2
Supercharge 22
First
Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};!
Observable!
.from(testIntData)!
.first()!
.subscribe(System.out::println);!
Supercharge 23
First
Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};!
Observable!
.from(testIntData)!
.first()!
.subscribe(System.out::println);!
// 1
Supercharge 24
Last
Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};!
Observable!
.from(testIntData)!
.last()!
.subscribe(System.out::println); !
Supercharge 25
Last
Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};!
Observable!
.from(testIntData)!
.last()!
.subscribe(System.out::println); !
// 5
Supercharge 26
Group by
Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};!
Observable!
.from(testIntData)!
.groupBy(integer -> integer % 2 == 0)!
.subscribe(grouped -> {!
grouped.toList().subscribe(groupedLists ->!
log(grouped.getKey() + " " + groupedLists)!
});!
});!
Supercharge 27
Group by
Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};!
Observable!
.from(testIntData)!
.groupBy(integer -> integer % 2 == 0)!
.subscribe(grouped -> {!
grouped.toList().subscribe(groupedLists ->!
log(grouped.getKey() + " " + groupedLists)!
});!
});!
Supercharge 28
Group by
Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};!
Observable!
.from(testIntData)!
.groupBy(integer -> integer % 2 == 0)!
.subscribe(grouped -> {!
grouped.toList().subscribe(groupedLists ->!
log(grouped.getKey() + " " + groupedLists) !
});!
});!
//false
//true
Supercharge 29
Group by
Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};!
Observable!
.from(testIntData)!
.groupBy(integer -> integer % 2 == 0)!
.subscribe(grouped -> {!
grouped.toList().subscribe(groupedLists ->!
log(grouped.getKey() + " " + groupedLists) !
});!
});!
//false 1, 3, 5
//true 2, 4
Supercharge 30
Distinct
String[] testDistinctData = new String[]{"a", "b", "a",
“c", "c", "d"};!
Observable!
.from(testDistinctData)!
.distinct()!
.subscribe(s -> log(s));!
Supercharge 31
Distinct
String[] testDistinctData = new String[]{"a", "b", "a",
“c", "c", "d"};!
Observable!
.from(testDistinctData)!
.distinct()!
.subscribe(s -> log(s));!
//a, b, c, d
Supercharge 32
Map
Observable.just("RxPresentation")!
.map(encoded -> Base64.encode(encoded.getBytes())
.subscribe(TestUtil::log);!
Supercharge 33
Map
Observable.just("RxPresentation")!
.map(encoded -> Base64.encode(encoded.getBytes())
.subscribe(TestUtil::log);!
//UnhQcmVzZW50YXRpb24=
Supercharge 34
Map
Observable.just("RxPresentation")!
.map(encoded -> Base64.encode(encoded.getBytes())
.map(s -> new String(Base64.decode(s))!
.subscribe(TestUtil::log);!
//RxPresentation
Supercharge 35
FlatMap
Observable.range(1, 6)!
.flatMap(integer -> getDataAsync(integer))!
.subscribe(TestUtil::log);!
Supercharge 36
FlatMap
Observable.range(1, 6)!
.flatMap(integer -> getDataAsync(integer))!
.subscribe(TestUtil::log);!
// 1, 2, 3, 4, 5, 6
Supercharge 37
FlatMap
Observable.range(1, 6)!
.flatMap(integer -> getDataAsync(integer))!
.subscribe(TestUtil::log);!
// 3, 5, 1, 2, 4, 6
Supercharge 38
Advanced Scenario
Advanced Scenario
Supercharge 40


Advanced Scenario
Supercharge 41
•  Imagine that you have a login screen.
Advanced Scenario
Supercharge 42
•  Imagine that you have a login screen.
•  Your task is to validate the input fields and if everything is good, you enable
the login button.
Advanced Scenario
Supercharge 43
•  Imagine that you have a login screen.
•  Your task is to validate the input fields and if everything is good, you enable
the login button.
•  After login, download all the data for the application.
Advanced Scenario
Supercharge 44
•  Imagine that you have a login screen.
•  Your task is to validate the input fields and if everything is good, you enable
the login button.
•  After login, download all the data for the application.
•  For example: the user has services and bills. You can get it from different
sources.
Advanced Scenario
Supercharge 45


Advanced Scenario
Supercharge 46


•  Validate the input fields.
!
Observable.combineLatest(!
RxTextView.textChangeEvents(mEmailView),!
RxTextView.textChangeEvents(mPasswordView),!
(emailChange, passwordChange) -> {!
boolean emailOK = emailChange.text().length() >= 3;!
boolean passOK = passwordChange.text().length() >= 3;!
!
return emailOK && passOK;!
})!
.compose(bindToLifecycle())!
.subscribe(isValid -> mSignIn.setEnabled(isValid));!
Advanced Scenario
Supercharge 47


•  RxBinding provides binding for android’s UI widgets.
!
Observable.combineLatest(!
RxTextView.textChangeEvents(mEmailView),!
RxTextView.textChangeEvents(mPasswordView),!
(emailChange, passwordChange) -> {!
boolean emailOK = emailChange.text().length() >= 3;!
boolean passOK = passwordChange.text().length() >= 3;!
!
return emailOK && passOK;!
})!
.compose(bindToLifecycle())!
.subscribe(isValid -> mSignIn.setEnabled(isValid));!
Advanced Scenario
Supercharge 48


•  Combine and evaluate the changes.
!
Observable.combineLatest(!
RxTextView.textChangeEvents(mEmailView),!
RxTextView.textChangeEvents(mPasswordView),!
(emailChange, passwordChange) -> {!
boolean emailOK = emailChange.text().length() >= 3;!
boolean passOK = passwordChange.text().length() >= 3;!
!
return emailOK && passOK;!
})!
.compose(bindToLifecycle())!
.subscribe(isValid -> mSignIn.setEnabled(isValid));!
Advanced Scenario
Supercharge 49


•  Use RxLifeCycle by Trello to properly handle subscriptions.
!
Observable.combineLatest(!
RxTextView.textChangeEvents(mEmailView),!
RxTextView.textChangeEvents(mPasswordView),!
(emailChange, passwordChange) -> {!
boolean emailOK = emailChange.text().length() >= 3;!
boolean passOK = passwordChange.text().length() >= 3;!
!
return emailOK && passOK;!
})!
.compose(bindToLifecycle())!
.subscribe(isValid -> mSignIn.setEnabled(isValid));!
Advanced Scenario
Supercharge 50


•  Enable/Disable Sign in button
!
Observable.combineLatest(!
RxTextView.textChangeEvents(mEmailView),!
RxTextView.textChangeEvents(mPasswordView),!
(emailChange, passwordChange) -> {!
boolean emailOK = emailChange.text().length() >= 3;!
boolean passOK = passwordChange.text().length() >= 3;!
!
return emailOK && passOK;!
})!
.compose(bindToLifecycle())!
.subscribe(isValid -> mSignIn.setEnabled(isValid));!
Advanced Scenario
Supercharge 51
•  Process services first.
Observable<Services> saveServices = apiManager.services()!
.compose(rxUtils.applySchedulers())!
.map(serviceResponse -> mapServices(serviceResponse))!
.doOnNext(services -> saveServices(services));!


Advanced Scenario
Supercharge 52
•  Download data with Retrofit
Observable<Services> saveServices = apiManager.services()!
.compose(rxUtils.applySchedulers())!
.map(serviceResponse -> mapServices(serviceResponse))!
.doOnNext(services -> saveServices(services));!


!
@GET("/services")!
Observable<ServiceResponse> services();!
Advanced Scenario
Supercharge 53
•  Apply schedulers
Observable<Services> saveServices = apiManager.services()!
.compose(rxUtils.applySchedulers())!
.map(serviceResponse -> mapServices(serviceResponse))!
.doOnNext(services -> saveServices(services));!


public <T> Observable.Transformer<T, T> applyDefaultSchedulers() {!
return obs-> obs.subscribeOn(Schedulers.io()) !
.observeOn(AndroidSchedulers.mainThread());!
}!
}!
Advanced Scenario
Supercharge 54
•  Apply schedulers
Observable<Services> saveServices = apiManager.services()!
.compose(rxUtils.applySchedulers())!
.map(serviceResponse -> mapServices(serviceResponse))!
.doOnNext(services -> saveServices(services));!


public <T> Observable.Transformer<T, T> applyDefaultSchedulers() {!
return obs-> obs.subscribeOn(Schedulers.io()) !
.observeOn(AndroidSchedulers.mainThread());!
}!
}!
Advanced Scenario
Supercharge 55
•  Apply schedulers
Observable<Services> saveServices = apiManager.services()!
.compose(rxUtils.applySchedulers())!
.map(serviceResponse -> mapServices(serviceResponse))!
.doOnNext(services -> saveServices(services));!


public <T> Observable.Transformer<T, T> applyDefaultSchedulers() {!
return obs-> obs.subscribeOn(Schedulers.io()) !
.observeOn(AndroidSchedulers.mainThread());!
}!
}!
Advanced Scenario
Supercharge 56
•  Map response to domain model
Observable<Services> saveServices = apiManager.services()!
.compose(rxUtils.applySchedulers())!
.map(serviceResponse -> mapServices(serviceResponse))!
.doOnNext(services -> saveServices(services));!


Transforms the items emitted by an Observable applying a function to each
item.
Advanced Scenario
Supercharge 57
•  Save data to database
Observable<Services> saveServices = apiManager.services()!
.compose(rxUtils.applySchedulers())!
.map(serviceResponse -> mapServices(serviceResponse))!
.doOnNext(services -> saveServices(services));!


Advanced Scenario
Supercharge 58
•  Do things parallel
Observable<Services> saveServices = apiManager.services()!
.compose(rxUtils.applySchedulers())!
.map(serviceResponse -> mapServices(serviceResponse))!
.doOnNext(services -> saveServices(services));!


Observable<Bills> saveBills = apiManager.bills()!
.compose(rxUtils.applySchedulers())!
.map(billResponse -> mapBills(billResponse))!
.doOnNext(bills -> saveBills(bills));!
Advanced Scenario
Supercharge 59
•  Do things parallel
Observable.zip(saveServices, saveBills, !
(s, b) -> new LoadingResult(s, b))!
.compose(rxComposer.applySchedulers())!
.subscribe(loadingResult -> log(loadingResult));!
Advanced Scenario
Supercharge 60
•  Do things parallel
Observable.zip(saveServices, saveBills, !
(s, b) -> new LoadingResult(s, b))!
.compose(rxComposer.applySchedulers())!
.subscribe(loadingResult -> log(loadingResult));!
static class LoadingResult{!
public LoadingResult(Services service, Bills bill) {…}!
}!
Testing
•  RxJava asynchronus by nature
Supercharge 61
Testing
•  RxJava asynchronus by nature
•  At first sight a bit complicated to test
Supercharge 62
Testing
•  RxJava asynchronus by nature
•  At first sight a bit complicated to test
•  Luckily RxJava and RxAndroid come with a couple of tools
Supercharge 63
Testing
•  What to test?
Supercharge 64
Testing
•  What to test?
–  Observables: composition of the various operators
Supercharge 65
Testing
•  What to test?
–  Observables: composition of the various operators
–  How the rest of app behaves while triggered by a subscription
Supercharge 66
Questions?
Thanks for your attention!
Contact us!
Richard Radics
Supercharge
Lead Android Developer
richard.radics@supercharge.io // www.supercharge.io
Functional Reactive Programming (RxJava) on Android

More Related Content

PPTX
Legacy Code Kata v3.0
William Munn
 
PPTX
Legacy Dependency Kata v2.0
William Munn
 
PDF
An Introduction to Property Based Testing
C4Media
 
PPTX
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMER
Andrey Karpov
 
PDF
Java Quiz - Meetup
CodeOps Technologies LLP
 
PDF
DSR Testing (Part 1)
Steve Upton
 
PPTX
Typescript barcelona
Christoffer Noring
 
PDF
Testing in android
jtrindade
 
Legacy Code Kata v3.0
William Munn
 
Legacy Dependency Kata v2.0
William Munn
 
An Introduction to Property Based Testing
C4Media
 
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMER
Andrey Karpov
 
Java Quiz - Meetup
CodeOps Technologies LLP
 
DSR Testing (Part 1)
Steve Upton
 
Typescript barcelona
Christoffer Noring
 
Testing in android
jtrindade
 

What's hot (10)

PDF
Angular Optimization Web Performance Meetup
David Barreto
 
PPT
Taverna tutorial
Rafael C. Jimenez
 
PPTX
Open sourcing the store
Mike Nakhimovich
 
PDF
DSR Testing (Part 2)
Steve Upton
 
PPTX
Qunit Java script Un
akanksha arora
 
PPTX
Firebase ng2 zurich
Christoffer Noring
 
PDF
Studying the impact of Social Structures on Software Quality
Nicolas Bettenburg
 
PPTX
Certification preparation - Error Handling and Troubleshooting recap.pptx
Rohit Radhakrishnan
 
PDF
Using Task Queues and D3.js to build an analytics product on App Engine
River of Talent
 
PDF
Metrics-Driven Engineering
Mike Brittain
 
Angular Optimization Web Performance Meetup
David Barreto
 
Taverna tutorial
Rafael C. Jimenez
 
Open sourcing the store
Mike Nakhimovich
 
DSR Testing (Part 2)
Steve Upton
 
Qunit Java script Un
akanksha arora
 
Firebase ng2 zurich
Christoffer Noring
 
Studying the impact of Social Structures on Software Quality
Nicolas Bettenburg
 
Certification preparation - Error Handling and Troubleshooting recap.pptx
Rohit Radhakrishnan
 
Using Task Queues and D3.js to build an analytics product on App Engine
River of Talent
 
Metrics-Driven Engineering
Mike Brittain
 
Ad

Similar to Functional Reactive Programming (RxJava) on Android (20)

PDF
Testing in FrontEnd World by Nikita Galkin
Sigma Software
 
PDF
Никита Галкин "Testing in Frontend World"
Fwdays
 
DOC
Cis 115 Education Redefined-snaptutorial.com
robertledwes38
 
PPTX
CONTROL STRUCTURE
Dr. Rosemarie Sibbaluca-Guirre
 
PDF
Model-based programming and AI-assisted software development
Eficode
 
PDF
Java Unit Testing Tool Competition — Fifth Round
Annibale Panichella
 
PDF
Monitoring Complex Systems: Keeping Your Head on Straight in a Hard World
Brian Troutwine
 
PPTX
E.D.D.I - Open Source Chatbot Platform
Gregor Jarisch
 
PDF
Angular 16 – the rise of Signals
Coding Academy
 
PPTX
refactoring code by clean code rules
saber tabatabaee
 
PDF
ParallelProgrammingBasics_v2.pdf
Chen-Hung Hu
 
PPTX
Introduction to C ++.pptx
VAIBHAVKADAGANCHI
 
PPTX
presentation on array java program operators
anushaashraf20
 
PPTX
Java Programming Course for beginners -الدسوقي
kareemtarek40
 
PPTX
Java developer trainee implementation and import
iamluqman0403
 
PPTX
Code instrumentation
Bryan Reinero
 
PPT
01SoftwEng.pptInnovation technology pptInnovation technology ppt
sultanahimed3
 
PPTX
Begin with c++ Fekra Course #1
Amr Alaa El Deen
 
PPTX
Code instrumentation
Mennan Tekbir
 
PDF
Java programming lab manual
sameer farooq
 
Testing in FrontEnd World by Nikita Galkin
Sigma Software
 
Никита Галкин "Testing in Frontend World"
Fwdays
 
Cis 115 Education Redefined-snaptutorial.com
robertledwes38
 
Model-based programming and AI-assisted software development
Eficode
 
Java Unit Testing Tool Competition — Fifth Round
Annibale Panichella
 
Monitoring Complex Systems: Keeping Your Head on Straight in a Hard World
Brian Troutwine
 
E.D.D.I - Open Source Chatbot Platform
Gregor Jarisch
 
Angular 16 – the rise of Signals
Coding Academy
 
refactoring code by clean code rules
saber tabatabaee
 
ParallelProgrammingBasics_v2.pdf
Chen-Hung Hu
 
Introduction to C ++.pptx
VAIBHAVKADAGANCHI
 
presentation on array java program operators
anushaashraf20
 
Java Programming Course for beginners -الدسوقي
kareemtarek40
 
Java developer trainee implementation and import
iamluqman0403
 
Code instrumentation
Bryan Reinero
 
01SoftwEng.pptInnovation technology pptInnovation technology ppt
sultanahimed3
 
Begin with c++ Fekra Course #1
Amr Alaa El Deen
 
Code instrumentation
Mennan Tekbir
 
Java programming lab manual
sameer farooq
 
Ad

Recently uploaded (20)

PDF
AI-Cloud-Business-Management-Platforms-The-Key-to-Efficiency-Growth.pdf
Artjoker Software Development Company
 
PPTX
What-is-the-World-Wide-Web -- Introduction
tonifi9488
 
PDF
NewMind AI Weekly Chronicles - July'25 - Week IV
NewMind AI
 
PPTX
IT Runs Better with ThousandEyes AI-driven Assurance
ThousandEyes
 
PDF
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
 
PDF
How Open Source Changed My Career by abdelrahman ismail
a0m0rajab1
 
PDF
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
PDF
Using Anchore and DefectDojo to Stand Up Your DevSecOps Function
Anchore
 
PDF
The Future of Mobile Is Context-Aware—Are You Ready?
iProgrammer Solutions Private Limited
 
PPTX
The-Ethical-Hackers-Imperative-Safeguarding-the-Digital-Frontier.pptx
sujalchauhan1305
 
PDF
Data_Analytics_vs_Data_Science_vs_BI_by_CA_Suvidha_Chaplot.pdf
CA Suvidha Chaplot
 
PDF
The Future of Artificial Intelligence (AI)
Mukul
 
PDF
BLW VOCATIONAL TRAINING SUMMER INTERNSHIP REPORT
codernjn73
 
PDF
Cloud-Migration-Best-Practices-A-Practical-Guide-to-AWS-Azure-and-Google-Clou...
Artjoker Software Development Company
 
PDF
A Strategic Analysis of the MVNO Wave in Emerging Markets.pdf
IPLOOK Networks
 
PDF
AI Unleashed - Shaping the Future -Starting Today - AIOUG Yatra 2025 - For Co...
Sandesh Rao
 
PDF
Advances in Ultra High Voltage (UHV) Transmission and Distribution Systems.pdf
Nabajyoti Banik
 
PDF
Event Presentation Google Cloud Next Extended 2025
minhtrietgect
 
PPTX
AI in Daily Life: How Artificial Intelligence Helps Us Every Day
vanshrpatil7
 
PDF
Software Development Methodologies in 2025
KodekX
 
AI-Cloud-Business-Management-Platforms-The-Key-to-Efficiency-Growth.pdf
Artjoker Software Development Company
 
What-is-the-World-Wide-Web -- Introduction
tonifi9488
 
NewMind AI Weekly Chronicles - July'25 - Week IV
NewMind AI
 
IT Runs Better with ThousandEyes AI-driven Assurance
ThousandEyes
 
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
 
How Open Source Changed My Career by abdelrahman ismail
a0m0rajab1
 
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
Using Anchore and DefectDojo to Stand Up Your DevSecOps Function
Anchore
 
The Future of Mobile Is Context-Aware—Are You Ready?
iProgrammer Solutions Private Limited
 
The-Ethical-Hackers-Imperative-Safeguarding-the-Digital-Frontier.pptx
sujalchauhan1305
 
Data_Analytics_vs_Data_Science_vs_BI_by_CA_Suvidha_Chaplot.pdf
CA Suvidha Chaplot
 
The Future of Artificial Intelligence (AI)
Mukul
 
BLW VOCATIONAL TRAINING SUMMER INTERNSHIP REPORT
codernjn73
 
Cloud-Migration-Best-Practices-A-Practical-Guide-to-AWS-Azure-and-Google-Clou...
Artjoker Software Development Company
 
A Strategic Analysis of the MVNO Wave in Emerging Markets.pdf
IPLOOK Networks
 
AI Unleashed - Shaping the Future -Starting Today - AIOUG Yatra 2025 - For Co...
Sandesh Rao
 
Advances in Ultra High Voltage (UHV) Transmission and Distribution Systems.pdf
Nabajyoti Banik
 
Event Presentation Google Cloud Next Extended 2025
minhtrietgect
 
AI in Daily Life: How Artificial Intelligence Helps Us Every Day
vanshrpatil7
 
Software Development Methodologies in 2025
KodekX
 

Functional Reactive Programming (RxJava) on Android

  • 1. Reactive Programming RxJava for android Richard Radics Lead Android Developer
  • 3. We experiment, we move fast, we make it happen At Supercharge we build high-impact mobile products making life easier for millions of users. Creating stunning experiences can only happen if you stretch yourself. To supercharge means to go that extra mile.
  • 4. Telekom RO The official self-care application of the Deutsche Telekom was completed within 14 weeks on iOS and Android. The application amassed nearly 1M downloads to date in the first launch country, Romania. The core functionality of the app became the model for DT’s European-wide self-care application and is expected to be rolled out in 8-10 countries in 2016. Supercharge currently maintains the core codebase and 3 countries.
  • 5. Jenius Indonesia’s fastest growing financial institute’s new app is an exciting example of modern mobile banking solutions. BTPN has over 100 million customer in the South East Asian region: their new app offers unique User Experience for all of them through its innovative functionality. Just to name a few interesting features: bill splitting enables coworkers to easily divide their lunch expenses, with the Cashtag function users can easily transfer money to “#someone” with the use of tagging. We are especially proud that our extremely effectively workflows and processes made it possible to reach the UAT phase of an app consisting of over 170 screens within 3 months of development (on two mobile platforms simultaneously). The application has been developed in cooperation with Misys.
  • 7. Reactive Programming Supercharge 7 Erik Meijer – Rx .Net Ben Christensen - RxJava
  • 8. ReactiveX •  Data Flow •  Observer Pattern •  Push vs Pull Supercharge 8
  • 12. From Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};! public Observable<Integer> fromExample() {! return Observable.from(testIntData);! }! ! ! Converts an iterable into an observable that emits all items in the iterable and calls onComplete. The resulting observable works synchronously. Supercharge 12
  • 13. From Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};! public Observable<Integer> fromExample() {! return Observable.from(testIntData);! }! ! ! Converts an iterable into an observable that emits all items in the iterable and calls onComplete. The resulting observable works synchronously. Supercharge 13
  • 14. Just Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};! public Observable<Integer[]> justExample() {! return Observable.just(testIntData);! }! Emit the object in onNext and calls onComplete. Does not try to iterate the object. Supercharge 14
  • 15. Just Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};! public Observable<Integer[]> justExample() {! return Observable.just(testIntData);! }! Emit the object in onNext and calls onComplete. Does not try to iterate the object. Supercharge 15
  • 16. Create Observable<Integer> getDataAsync(int i) {! return getDataSync(i).subscribeOn(Schedulers.io());! }! Observable<Integer> getDataSync(int i) {! return Observable.create(subscriber -> {! try { ! Thread.sleep(rand(100, 500)); ! subscriber.onNext(i);! subscriber.onCompleted();! }catch (Exception e){! subscriber.onError(e);! }! });! }! Supercharge 16
  • 17. Create Observable<Integer> getDataAsync(int i) {! return getDataSync(i).subscribeOn(Schedulers.io());! }! Observable<Integer> getDataSync(int i) {! return Observable.create(subscriber -> {! try { ! Thread.sleep(rand(100, 500)); ! subscriber.onNext(i);! subscriber.onCompleted();! }catch (Exception e){! subscriber.onError(e);! }! });! } Supercharge 17
  • 19. Filter Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};! Observable! .from(testIntData)! .filter(integer -> integer % 2 == 0)! .subscribe(System.out::println);! Supercharge 19
  • 20. Filter Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};! Observable! .from(testIntData)! .filter(integer -> integer % 2 == 0)! .subscribe(System.out::println);! // 2 // 4 Supercharge 20
  • 21. Take first N values Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};! Observable! .from(testIntData)! .take(2)! .subscribe(System.out::println);! ! ! Supercharge 21
  • 22. Take first N values Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};! Observable! .from(testIntData)! .take(2)! .subscribe(System.out::println);! // 1 // 2 Supercharge 22
  • 23. First Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};! Observable! .from(testIntData)! .first()! .subscribe(System.out::println);! Supercharge 23
  • 24. First Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};! Observable! .from(testIntData)! .first()! .subscribe(System.out::println);! // 1 Supercharge 24
  • 25. Last Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};! Observable! .from(testIntData)! .last()! .subscribe(System.out::println); ! Supercharge 25
  • 26. Last Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};! Observable! .from(testIntData)! .last()! .subscribe(System.out::println); ! // 5 Supercharge 26
  • 27. Group by Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};! Observable! .from(testIntData)! .groupBy(integer -> integer % 2 == 0)! .subscribe(grouped -> {! grouped.toList().subscribe(groupedLists ->! log(grouped.getKey() + " " + groupedLists)! });! });! Supercharge 27
  • 28. Group by Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};! Observable! .from(testIntData)! .groupBy(integer -> integer % 2 == 0)! .subscribe(grouped -> {! grouped.toList().subscribe(groupedLists ->! log(grouped.getKey() + " " + groupedLists)! });! });! Supercharge 28
  • 29. Group by Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};! Observable! .from(testIntData)! .groupBy(integer -> integer % 2 == 0)! .subscribe(grouped -> {! grouped.toList().subscribe(groupedLists ->! log(grouped.getKey() + " " + groupedLists) ! });! });! //false //true Supercharge 29
  • 30. Group by Integer[] testIntData = new Integer[]{1, 2, 3, 4, 5};! Observable! .from(testIntData)! .groupBy(integer -> integer % 2 == 0)! .subscribe(grouped -> {! grouped.toList().subscribe(groupedLists ->! log(grouped.getKey() + " " + groupedLists) ! });! });! //false 1, 3, 5 //true 2, 4 Supercharge 30
  • 31. Distinct String[] testDistinctData = new String[]{"a", "b", "a", “c", "c", "d"};! Observable! .from(testDistinctData)! .distinct()! .subscribe(s -> log(s));! Supercharge 31
  • 32. Distinct String[] testDistinctData = new String[]{"a", "b", "a", “c", "c", "d"};! Observable! .from(testDistinctData)! .distinct()! .subscribe(s -> log(s));! //a, b, c, d Supercharge 32
  • 35. Map Observable.just("RxPresentation")! .map(encoded -> Base64.encode(encoded.getBytes()) .map(s -> new String(Base64.decode(s))! .subscribe(TestUtil::log);! //RxPresentation Supercharge 35
  • 36. FlatMap Observable.range(1, 6)! .flatMap(integer -> getDataAsync(integer))! .subscribe(TestUtil::log);! Supercharge 36
  • 37. FlatMap Observable.range(1, 6)! .flatMap(integer -> getDataAsync(integer))! .subscribe(TestUtil::log);! // 1, 2, 3, 4, 5, 6 Supercharge 37
  • 38. FlatMap Observable.range(1, 6)! .flatMap(integer -> getDataAsync(integer))! .subscribe(TestUtil::log);! // 3, 5, 1, 2, 4, 6 Supercharge 38
  • 41. Advanced Scenario Supercharge 41 •  Imagine that you have a login screen.
  • 42. Advanced Scenario Supercharge 42 •  Imagine that you have a login screen. •  Your task is to validate the input fields and if everything is good, you enable the login button.
  • 43. Advanced Scenario Supercharge 43 •  Imagine that you have a login screen. •  Your task is to validate the input fields and if everything is good, you enable the login button. •  After login, download all the data for the application.
  • 44. Advanced Scenario Supercharge 44 •  Imagine that you have a login screen. •  Your task is to validate the input fields and if everything is good, you enable the login button. •  After login, download all the data for the application. •  For example: the user has services and bills. You can get it from different sources.
  • 46. Advanced Scenario Supercharge 46 
 •  Validate the input fields. ! Observable.combineLatest(! RxTextView.textChangeEvents(mEmailView),! RxTextView.textChangeEvents(mPasswordView),! (emailChange, passwordChange) -> {! boolean emailOK = emailChange.text().length() >= 3;! boolean passOK = passwordChange.text().length() >= 3;! ! return emailOK && passOK;! })! .compose(bindToLifecycle())! .subscribe(isValid -> mSignIn.setEnabled(isValid));!
  • 47. Advanced Scenario Supercharge 47 
 •  RxBinding provides binding for android’s UI widgets. ! Observable.combineLatest(! RxTextView.textChangeEvents(mEmailView),! RxTextView.textChangeEvents(mPasswordView),! (emailChange, passwordChange) -> {! boolean emailOK = emailChange.text().length() >= 3;! boolean passOK = passwordChange.text().length() >= 3;! ! return emailOK && passOK;! })! .compose(bindToLifecycle())! .subscribe(isValid -> mSignIn.setEnabled(isValid));!
  • 48. Advanced Scenario Supercharge 48 
 •  Combine and evaluate the changes. ! Observable.combineLatest(! RxTextView.textChangeEvents(mEmailView),! RxTextView.textChangeEvents(mPasswordView),! (emailChange, passwordChange) -> {! boolean emailOK = emailChange.text().length() >= 3;! boolean passOK = passwordChange.text().length() >= 3;! ! return emailOK && passOK;! })! .compose(bindToLifecycle())! .subscribe(isValid -> mSignIn.setEnabled(isValid));!
  • 49. Advanced Scenario Supercharge 49 
 •  Use RxLifeCycle by Trello to properly handle subscriptions. ! Observable.combineLatest(! RxTextView.textChangeEvents(mEmailView),! RxTextView.textChangeEvents(mPasswordView),! (emailChange, passwordChange) -> {! boolean emailOK = emailChange.text().length() >= 3;! boolean passOK = passwordChange.text().length() >= 3;! ! return emailOK && passOK;! })! .compose(bindToLifecycle())! .subscribe(isValid -> mSignIn.setEnabled(isValid));!
  • 50. Advanced Scenario Supercharge 50 
 •  Enable/Disable Sign in button ! Observable.combineLatest(! RxTextView.textChangeEvents(mEmailView),! RxTextView.textChangeEvents(mPasswordView),! (emailChange, passwordChange) -> {! boolean emailOK = emailChange.text().length() >= 3;! boolean passOK = passwordChange.text().length() >= 3;! ! return emailOK && passOK;! })! .compose(bindToLifecycle())! .subscribe(isValid -> mSignIn.setEnabled(isValid));!
  • 51. Advanced Scenario Supercharge 51 •  Process services first. Observable<Services> saveServices = apiManager.services()! .compose(rxUtils.applySchedulers())! .map(serviceResponse -> mapServices(serviceResponse))! .doOnNext(services -> saveServices(services));! 

  • 52. Advanced Scenario Supercharge 52 •  Download data with Retrofit Observable<Services> saveServices = apiManager.services()! .compose(rxUtils.applySchedulers())! .map(serviceResponse -> mapServices(serviceResponse))! .doOnNext(services -> saveServices(services));! 
 ! @GET("/services")! Observable<ServiceResponse> services();!
  • 53. Advanced Scenario Supercharge 53 •  Apply schedulers Observable<Services> saveServices = apiManager.services()! .compose(rxUtils.applySchedulers())! .map(serviceResponse -> mapServices(serviceResponse))! .doOnNext(services -> saveServices(services));! 
 public <T> Observable.Transformer<T, T> applyDefaultSchedulers() {! return obs-> obs.subscribeOn(Schedulers.io()) ! .observeOn(AndroidSchedulers.mainThread());! }! }!
  • 54. Advanced Scenario Supercharge 54 •  Apply schedulers Observable<Services> saveServices = apiManager.services()! .compose(rxUtils.applySchedulers())! .map(serviceResponse -> mapServices(serviceResponse))! .doOnNext(services -> saveServices(services));! 
 public <T> Observable.Transformer<T, T> applyDefaultSchedulers() {! return obs-> obs.subscribeOn(Schedulers.io()) ! .observeOn(AndroidSchedulers.mainThread());! }! }!
  • 55. Advanced Scenario Supercharge 55 •  Apply schedulers Observable<Services> saveServices = apiManager.services()! .compose(rxUtils.applySchedulers())! .map(serviceResponse -> mapServices(serviceResponse))! .doOnNext(services -> saveServices(services));! 
 public <T> Observable.Transformer<T, T> applyDefaultSchedulers() {! return obs-> obs.subscribeOn(Schedulers.io()) ! .observeOn(AndroidSchedulers.mainThread());! }! }!
  • 56. Advanced Scenario Supercharge 56 •  Map response to domain model Observable<Services> saveServices = apiManager.services()! .compose(rxUtils.applySchedulers())! .map(serviceResponse -> mapServices(serviceResponse))! .doOnNext(services -> saveServices(services));! 
 Transforms the items emitted by an Observable applying a function to each item.
  • 57. Advanced Scenario Supercharge 57 •  Save data to database Observable<Services> saveServices = apiManager.services()! .compose(rxUtils.applySchedulers())! .map(serviceResponse -> mapServices(serviceResponse))! .doOnNext(services -> saveServices(services));! 

  • 58. Advanced Scenario Supercharge 58 •  Do things parallel Observable<Services> saveServices = apiManager.services()! .compose(rxUtils.applySchedulers())! .map(serviceResponse -> mapServices(serviceResponse))! .doOnNext(services -> saveServices(services));! 
 Observable<Bills> saveBills = apiManager.bills()! .compose(rxUtils.applySchedulers())! .map(billResponse -> mapBills(billResponse))! .doOnNext(bills -> saveBills(bills));!
  • 59. Advanced Scenario Supercharge 59 •  Do things parallel Observable.zip(saveServices, saveBills, ! (s, b) -> new LoadingResult(s, b))! .compose(rxComposer.applySchedulers())! .subscribe(loadingResult -> log(loadingResult));!
  • 60. Advanced Scenario Supercharge 60 •  Do things parallel Observable.zip(saveServices, saveBills, ! (s, b) -> new LoadingResult(s, b))! .compose(rxComposer.applySchedulers())! .subscribe(loadingResult -> log(loadingResult));! static class LoadingResult{! public LoadingResult(Services service, Bills bill) {…}! }!
  • 61. Testing •  RxJava asynchronus by nature Supercharge 61
  • 62. Testing •  RxJava asynchronus by nature •  At first sight a bit complicated to test Supercharge 62
  • 63. Testing •  RxJava asynchronus by nature •  At first sight a bit complicated to test •  Luckily RxJava and RxAndroid come with a couple of tools Supercharge 63
  • 64. Testing •  What to test? Supercharge 64
  • 65. Testing •  What to test? –  Observables: composition of the various operators Supercharge 65
  • 66. Testing •  What to test? –  Observables: composition of the various operators –  How the rest of app behaves while triggered by a subscription Supercharge 66
  • 68. Thanks for your attention! Contact us! Richard Radics Supercharge Lead Android Developer [email protected] // www.supercharge.io