SlideShare a Scribd company logo
@fernando_cejas
http://www.fernandocejas.com
The Mayans Lost Guide
To RxJava on Android
@fernando_cejas
Curious learner
Meet...
Android lover
Software engineer
Geek
The Mayans Lost Guide to RxJava on Android
#Reactive
1- of, relating to, or marked by reaction or
reactance.
2- readily responsive to a stimulus.
RxJava is a Java VM implementation
of Reactive X (Reactive Extensions): ˝
a library for composing asynchronous
and event-based programs by using
observable sequences.
What is RxJava?
Why should
we go
reactive?
Multithreading is always complex˝
Concurrency˝
Java Futures are Expensive to Compose˝
Java Futures˝
Callbacks Have Their Own Problems˝
Callbacks˝
@benjchristensen from @netflix
public class FuturesA {
public static void run() throws Exception {
ExecutorService executor =
new ThreadPoolExecutor(4, 4, 1,
TimeUnit.MINUTES,
new LinkedBlockingQueue<Runnable>());
Future<String> f1 = executor.submit(new CallToRemoteServiceA());
Future<String> f2 = executor.submit(new CallToRemoteServiceB());
System.out.println(f1.get() + " - " + f2.get());
}
}
https://gist.github.com/benjchristensen/4670979
#Java Futures
#Java Futures
https://gist.github.com/benjchristensen/4671081
public static void run() throws Exception {
ExecutorService executor =
new ThreadPoolExecutor(4, 4, 1,
TimeUnit.MINUTES,
new LinkedBlockingQueue<Runnable>());
try {
// get f3 with dependent result from f1
Future<String> f1 = executor.submit(new CallToRemoteServiceA());
Future<String> f3 = executor.submit(new CallToRemoteServiceC(f1.get()));
/* The work below can not proceed until f1.get()
completes even though there is no dependency */
// also get f4/f5 after dependency f2 completes
Future<Integer> f2 = executor.submit(new CallToRemoteServiceB());
Future<Integer> f4 = executor.submit(new CallToRemoteServiceD(f2.get()));
Future<Integer> f5 = executor.submit(new CallToRemoteServiceE(f2.get()));
System.out.println(f3.get() + " => " + (f4.get() * f5.get()));
} finally {
executor.shutdownNow();
}
}
#Java Futures
https://gist.github.com/benjchristensen/4671081
public static void run4() throws Exception {
ExecutorService executor =
new ThreadPoolExecutor(4, 4, 1,
TimeUnit.MINUTES,
new LinkedBlockingQueue<Runnable>());
try {
List<Future<?>> futures = new ArrayList<Future<?>>();
// kick off several async tasks
futures.add(executor.submit(new CallToRemoteServiceA()));
futures.add(executor.submit(new CallToRemoteServiceB()));
futures.add(executor.submit(new CallToRemoteServiceC("A")));
futures.add(executor.submit(new CallToRemoteServiceC("B")));
futures.add(executor.submit(new CallToRemoteServiceD(1)));
futures.add(executor.submit(new CallToRemoteServiceE(2)));
futures.add(executor.submit(new CallToRemoteServiceE(3)));
// as each completes do further work
for (Future<?> f : futures) {
/* this blocks so even if other futures in the list
complete earlier they will wait until this one is done */
doMoreWork(f.get());
}
} finally {
executor.shutdownNow();
}
}
Multithreading is always complex˝
Concurrency˝
Java Futures are Expensive to Compose˝
Java Futures˝
Callbacks Have Their Own Problems˝
Callbacks˝
@benjchristensen from @netflix
#Callbacks
https://gist.github.com/benjchristensen/4677544
...
// get f3 with dependent result from f1
executor.execute(new CallToRemoteServiceA(new Callback<String>() {
@Override
public void call(String f1) {
executor.execute(new CallToRemoteServiceC(new Callback<String>() {
@Override
public void call(String f3) {
// we have f1 and f3 now need to compose with others
System.out.println("intermediate callback: " + f3 + " => " + ("f4 * f5"));
// set to thread-safe variable accessible by external scope
f3Value.set(f3);
latch.countDown();
}
}, f1));
}
}));
...
Observables
Subscribers
Subscriptions
Schedulers
Operators
#RxJava Guys:
Observables
The Observable object is who
does the job.
Represents an object that sends
notifications (Provider) to a
Subscriptor (Observer).
Observables
Add 2 missing semantics to the
Observer pattern:
#1: Emits a signal to the consumer
when there is no more data available.
#2: Emits a signal to the consumer
when an error has occurred.
Observables
Observables
Subscribers
Subscribers provides a
mechanism for receiving push-
based notifications from
Observables, and permits
manual unsubscribing from
these Observables.
Subscribers
Not an observer pattern:
Observables often don't
start emitting items until
someone explicitly
subscribes to them.
Subscribers
Observables often don't
start emitting items until
someone explicitly
subscribes to them.
Subscribers
public class DefaultSubscriber<T> extends rx.Subscriber<T> {
@Override public void onCompleted() {
}
@Override public void onError(Throwable e) {
}
@Override public void onNext(T t) {
}
}
Subscriptions
Subscriptions represents the link
between your Observable and
your Subscriber.
#1: Subscriptions
#2: CompositeSubscriptions
#1: Schedulers.io()
#2: Schedulers.computation()
#3: Schedulers.from()
Schedulers
If you want to introduce multithreading into
your cascade of Observable operators, you
can do so by instructing those operators (or
particular Observables) to operate on
particular Schedulers.
Operators
Operators can be used in
between the source Observable
and the ultimate Subscriber to
manipulate emitted items.
You can even write your own
custom operators.
map()
Transform the items emitted by an Observable
by applying a function to each item.
flatMap()
Transforms the items emitted by an
Observable into Observables, then flatten the
emissions from those into a single Observable
(no order)
concatMap()
Transforms the items emitted by an
Observable into Observables, then flatten the
emissions from those into a single Observable
(keeps order)
flatMap() vs concatMap()
http://fernandocejas.com/2015/01/11/rxjava-observable-tranformation-concatmap-vs-flatmap/
filter()
Emits the same item it received, but only if it
passes the boolean check (predicate).
take()
Emit only the first n items emitted by an
Observable
doOnNext()
Allows us to add extra behavior each time an
item is emitted.
onError() is called if an
exception is thrown at any time.
Error handling
The operators do not have to
handle the exception.
onErrorResumeNext()
Instructs an Observable to emit a sequence of items if it
encounters an error.
onErrorReturn()
Instructs an Observable to emit a particular item when it
encounters an error.
onExceptionResumeNext()
Instructs an Observable to continue emitting items after it
encounters an exception.
retry()
If a source Observable emits an error, resubscribe to it in the
hopes that it will complete without error.
retryWhen()
If a source Observable emits an error, pass that error to another
Observable to determine whether to resubscribe to the source.
Error handling Operators
#1: Observable and Subscriber can do
anything
#2: The Observable and Subscriber are
independent of the transformational
steps in between them.
#3: Operators let you do anything to the
stream of data.
Key ideas behind RxJava
http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/
#1: Learning curve
#2: Too many anonymous classes
generated (OutOfMemory?)
#3: Verbosity (retrolambda to the
rescue?)
But there are some pitfalls…
#Example: Clean Architecture
#Example: Clean Architecture
@PerActivity
public class UserListPresenter extends DefaultSubscriber<List<User>>
implements Presenter {
private UserListView viewListView;
private final UseCase getUserListUseCase;
@Inject
public UserListPresenter(@Named("userList") UseCase getUserListUserCase,
UserModelDataMapper userModelDataMapper) {
this.getUserListUseCase = getUserListUserCase;
}
@Override public void destroy() {
this.getUserListUseCase.unsubscribe();
}
private void getUserList() {
this.getUserListUseCase.execute(this);
}
...
}
#Example: Reactive Presenter
#Example: Reactive Presenter
@PerActivity
public class UserListPresenter extends DefaultSubscriber<List<User>>
implements Presenter {
...
@Override public void onCompleted() {
this.hideViewLoading();
}
@Override public void onError(Throwable e) {
this.hideViewLoading();
this.showErrorMessage(new DefaultErrorBundle((Exception) e));
this.showViewRetry();
}
@Override public void onNext(List<User> users) {
this.showUsersCollectionInView(users);
}
}
#Example: Clean Architecture
#Example: UseCase
public abstract class UseCase {
private final ThreadExecutor threadExecutor;
private final PostExecutionThread postExecutionThread;
private Subscription subscription = Subscriptions.empty();
protected UseCase(ThreadExecutor threadExecutor, PostExecutionThread postExecutionThread) {
this.threadExecutor = threadExecutor;
this.postExecutionThread = postExecutionThread;
}
protected abstract Observable buildUseCaseObservable();
public void execute(Subscriber UseCaseSubscriber) {
this.subscription = this.buildUseCaseObservable()
.subscribeOn(Schedulers.from(threadExecutor))
.observeOn(postExecutionThread.getScheduler())
.subscribe(UseCaseSubscriber);
}
public void unsubscribe() {
if (!subscription.isUnsubscribed()) subscription.unsubscribe();
}
}
#Example: Execution Thread
/**
* MainThread (UI Thread) implementation based on a
* {@link rx.Scheduler} which will execute actions on
* the Android UI thread
*/
@Singleton
public class UIThread implements PostExecutionThread {
@Inject
public UIThread() {}
@Override public Scheduler getScheduler() {
return AndroidSchedulers.mainThread();
}
}
#Example: UseCase
/**
* This class is an implementation of {@link UseCase} that represents a
* use case for retrieving a collection of all {@link User}.
*/
public class GetUserListUseCase extends UseCase {
private final UserRepository userRepository;
@Inject
public GetUserListUseCase(UserRepository userRepository,
ThreadExecutor threadExecutor,
PostExecutionThread postExecutionThread) {
super(threadExecutor, postExecutionThread);
this.userRepository = userRepository;
}
@Override public Observable buildUseCaseObservable() {
return this.userRepository.getUsers();
}
}
#Example: Clean Architecture
#Example: Operator and Action
public class CloudUserDataStore implements UserDataStore {
private final RestApi restApi;
private final UserCache userCache;
private final Action1<UserEntity> saveToCacheAction = new Action1<UserEntity>() {
@Override public void call(UserEntity userEntity) {
if (userEntity != null) {
CloudUserDataStore.this.userCache.put(userEntity);
}
}
};
public CloudUserDataStore(RestApi restApi, UserCache userCache) {
this.restApi = restApi;
this.userCache = userCache;
}
@Override public Observable<List<UserEntity>> getUserEntityList() {
return this.restApi.getUserEntityList();
}
@Override public Observable<UserEntity> getUserEntityDetails(final int userId) {
return this.restApi.getUserEntityById(userId).doOnNext(saveToCacheAction);
}
}
#Example: Data transformation
@Singleton
public class UserDataRepository implements UserRepository {
private final UserDataStoreFactory userDataStoreFactory;
private final UserEntityDataMapper userEntityDataMapper;
private final Func1<List<UserEntity>, List<User>> userListEntityMapper =
new Func1<List<UserEntity>, List<User>>() {
@Override public List<User> call(List<UserEntity> userEntities) {
return UserDataRepository.this.userEntityDataMapper.transform(userEntities);
}
};
private final Func1<UserEntity, User>
userDetailsEntityMapper = new Func1<UserEntity, User>() {
@Override public User call(UserEntity userEntity) {
return UserDataRepository.this.userEntityDataMapper.transform(userEntity);
}
};
@Override public Observable<List<User>> getUsers() {
final UserDataStore userDataStore = this.userDataStoreFactory.createCloudDataStore();
return userDataStore.getUserEntityList().map(userListEntityMapper);
}
}
#Example: Observable creation
@Override public Observable<List<UserEntity>> getUserEntityList() {
return Observable.create(new Observable.OnSubscribe<List<UserEntity>>() {
@Override public void call(Subscriber<? super List<UserEntity>> subscriber) {
if (isThereInternetConnection()) {
try {
String responseUserEntities = getUserEntitiesFromApi();
subscriber.onNext(userEntityJsonMapper.transformUserEntityCollection(
responseUserEntities));
subscriber.onCompleted();
} catch (Exception e) {
subscriber.onError(new NetworkConnectionException(e.getCause()));
}
} else {
subscriber.onError(new NetworkConnectionException());
}
}
});
}
#1: Good starting point to switch to Rx
Observables.
#2: No need to deal with threading an
synchronization.
#3: Very simple to wrap an http
connection in an Observable
How do I start with RxJava?
Rx at data level
#1: We can convert our events into Rx
Observables
How do I start with RxJava?
Rx at view level
Observable input = Observable.FromEventPattern(textView, "TextChanged")
.Select(_ => textbox.Text)
.Throttle(TimeSpan.FromSeconds(0.5))
.DistinctUntilChanged();
#1: You will return Rx Observables in
domain layer.
#2: Be careful with side effects (Rx
Schedulers other than UI Thread)
How do I start with RxJava?
Rx at domain level
#1: By default, RxJava is synchronous.
#2: onSubscribe() is executed separately
for every new subscriber.
#3: Subscriptions leak memory.
Tips and Tricks
#4: Read the official documentation
References
Reactive Programming on Android With RxJava
https://mttkay.github.io/blog/2013/08/25/functional-reactive-programming-on-android-with-rxjava/
Grokking RxJava
http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/
Reactive Programming in the Netflix API with RxJava
http://techblog.netflix.com/2013/02/rxjava-netflix-api.html
Rx for .NET and RxJava for Android
http://futurice.com/blog/tech-pick-of-the-week-rx-for-net-and-rxjava-for-android
https://github.com/android10/Android-CleanArchitecture
Official Documentation
https://github.com/ReactiveX/RxJava/wiki
https://github.com/android10/Android-ReactiveProgramming
?˝
Source: US Census Bureau
Questions
@fernando_cejas
http://soundcloud.com/jobs
Thanks!

More Related Content

PDF
RxJava@Android
PPTX
Reactive Programming on Android - RxAndroid - RxJava
PPTX
Introduction to RxJava on Android
PDF
Reactive Android: RxJava and beyond
PDF
RxJava for Android - GDG DevFest Ukraine 2015
PPTX
Reactive programming with RxAndroid
PDF
Streams, Streams Everywhere! An Introduction to Rx
PDF
Introduction to Retrofit and RxJava
RxJava@Android
Reactive Programming on Android - RxAndroid - RxJava
Introduction to RxJava on Android
Reactive Android: RxJava and beyond
RxJava for Android - GDG DevFest Ukraine 2015
Reactive programming with RxAndroid
Streams, Streams Everywhere! An Introduction to Rx
Introduction to Retrofit and RxJava

What's hot (20)

PPTX
Reactive Java (33rd Degree)
PPTX
Reactive Java (GeeCON 2014)
PDF
Reactive Thinking in Java
PDF
Reactive programming using rx java & akka actors - pdx-scala - june 2014
PPTX
Intro to Functional Programming with RxJava
PPTX
Introduction to Reactive Java
PDF
Angular & RXJS: examples and use cases
PDF
Java concurrency model - The Future Task
PDF
My Gentle Introduction to RxJS
PPTX
RxJS and Reactive Programming - Modern Web UI - May 2015
PPTX
Code craftsmanship saturdays second session
PPTX
React hooks
PDF
Annotation Processing - Demystifying Java's Dark Arts
PPTX
Rx java in action
PDF
Martin Anderson - threads v actors
PDF
The Future of Futures - A Talk About Java 8 CompletableFutures
PDF
JavaOne 2013: Java 8 - The Good Parts
PPTX
MVVM and RxJava – the perfect mix
PDF
Reactive programming in Angular 2
PPTX
Reactive Extensions for JavaScript
Reactive Java (33rd Degree)
Reactive Java (GeeCON 2014)
Reactive Thinking in Java
Reactive programming using rx java & akka actors - pdx-scala - june 2014
Intro to Functional Programming with RxJava
Introduction to Reactive Java
Angular & RXJS: examples and use cases
Java concurrency model - The Future Task
My Gentle Introduction to RxJS
RxJS and Reactive Programming - Modern Web UI - May 2015
Code craftsmanship saturdays second session
React hooks
Annotation Processing - Demystifying Java's Dark Arts
Rx java in action
Martin Anderson - threads v actors
The Future of Futures - A Talk About Java 8 CompletableFutures
JavaOne 2013: Java 8 - The Good Parts
MVVM and RxJava – the perfect mix
Reactive programming in Angular 2
Reactive Extensions for JavaScript
Ad

Viewers also liked (12)

PDF
Material Design for Old Schoolers
PPTX
2 презентация rx java+android
PDF
RxJava for Android - GDG and DataArt
PDF
RxJava on Android
PDF
RxJava on Android
PPTX
Introduction to rx java for android
PDF
Rxjava 介紹與 Android 中的 RxJava
PDF
Practical RxJava for Android
PPTX
Headless fragments in Android
PDF
Building Scalable Stateless Applications with RxJava
PDF
A pattern language for microservices (#gluecon #gluecon2016)
PDF
Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...
Material Design for Old Schoolers
2 презентация rx java+android
RxJava for Android - GDG and DataArt
RxJava on Android
RxJava on Android
Introduction to rx java for android
Rxjava 介紹與 Android 中的 RxJava
Practical RxJava for Android
Headless fragments in Android
Building Scalable Stateless Applications with RxJava
A pattern language for microservices (#gluecon #gluecon2016)
Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...
Ad

Similar to The Mayans Lost Guide to RxJava on Android (20)

PPTX
Reactive Programming in Java 8 with Rx-Java
PDF
How to Think in RxJava Before Reacting
PPTX
Intro to Reactive Thinking and RxJava 2
PDF
RxJava - introduction & design
PPTX
Rxandroid
PPTX
RxAndroid
PPTX
Reactive programming with rx java
PDF
Reactive programming on Android
PDF
RxJava@DAUG
PDF
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
PDF
Reactive Programming for a demanding world: building event-driven and respons...
PDF
Reactive programming on Android
PPTX
RxJava 2 Reactive extensions for the JVM
PPTX
Rx presentation
PDF
Saving lives with rx java
PPTX
RxJava2 Slides
PPTX
Javantura v3 - Going Reactive with RxJava – Hrvoje Crnjak
PDF
Reactive java - Reactive Programming + RxJava
PDF
RxJava in practice
PPTX
An Introduction to RxJava
Reactive Programming in Java 8 with Rx-Java
How to Think in RxJava Before Reacting
Intro to Reactive Thinking and RxJava 2
RxJava - introduction & design
Rxandroid
RxAndroid
Reactive programming with rx java
Reactive programming on Android
RxJava@DAUG
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Reactive Programming for a demanding world: building event-driven and respons...
Reactive programming on Android
RxJava 2 Reactive extensions for the JVM
Rx presentation
Saving lives with rx java
RxJava2 Slides
Javantura v3 - Going Reactive with RxJava – Hrvoje Crnjak
Reactive java - Reactive Programming + RxJava
RxJava in practice
An Introduction to RxJava

More from Fernando Cejas (14)

PDF
It is about philosophy: culture of a good programmer
PDF
How to Become the MacGyver of Android Custom Views
PDF
Android UX-UI Design for Fun and Profit
PDF
How ANDROID TESTING changed how we think about Death - Second Edition
PDF
How ANDROID TESTING changed how we think about Death
PDF
Dinosaurs and Androids: The Listview Evolution
PDF
Inside Android Testing
PDF
Webview: The fifth element
PPTX
Nfc on Android
PPTX
Android Design Patterns
PPTX
Android Cloud To Device Messaging
PPTX
Android Quick Introduction
PPT
Desarrollo android almacenamiento de datos
PPTX
Android simple 2d Layout animation
It is about philosophy: culture of a good programmer
How to Become the MacGyver of Android Custom Views
Android UX-UI Design for Fun and Profit
How ANDROID TESTING changed how we think about Death - Second Edition
How ANDROID TESTING changed how we think about Death
Dinosaurs and Androids: The Listview Evolution
Inside Android Testing
Webview: The fifth element
Nfc on Android
Android Design Patterns
Android Cloud To Device Messaging
Android Quick Introduction
Desarrollo android almacenamiento de datos
Android simple 2d Layout animation

Recently uploaded (20)

PDF
Human-AI Collaboration: Balancing Agentic AI and Autonomy in Hybrid Systems
PDF
Automation-in-Manufacturing-Chapter-Introduction.pdf
PDF
Level 2 – IBM Data and AI Fundamentals (1)_v1.1.PDF
PDF
UNIT no 1 INTRODUCTION TO DBMS NOTES.pdf
PDF
BIO-INSPIRED HORMONAL MODULATION AND ADAPTIVE ORCHESTRATION IN S-AI-GPT
PDF
null (2) bgfbg bfgb bfgb fbfg bfbgf b.pdf
PPTX
Safety Seminar civil to be ensured for safe working.
PPTX
Fundamentals of Mechanical Engineering.pptx
PDF
Visual Aids for Exploratory Data Analysis.pdf
PDF
Abrasive, erosive and cavitation wear.pdf
PPTX
AUTOMOTIVE ENGINE MANAGEMENT (MECHATRONICS).pptx
PPTX
Module 8- Technological and Communication Skills.pptx
PPTX
Management Information system : MIS-e-Business Systems.pptx
PDF
Soil Improvement Techniques Note - Rabbi
PDF
III.4.1.2_The_Space_Environment.p pdffdf
PPTX
introduction to high performance computing
PDF
BIO-INSPIRED ARCHITECTURE FOR PARSIMONIOUS CONVERSATIONAL INTELLIGENCE : THE ...
PDF
Design Guidelines and solutions for Plastics parts
PDF
Unit I ESSENTIAL OF DIGITAL MARKETING.pdf
PPT
Occupational Health and Safety Management System
Human-AI Collaboration: Balancing Agentic AI and Autonomy in Hybrid Systems
Automation-in-Manufacturing-Chapter-Introduction.pdf
Level 2 – IBM Data and AI Fundamentals (1)_v1.1.PDF
UNIT no 1 INTRODUCTION TO DBMS NOTES.pdf
BIO-INSPIRED HORMONAL MODULATION AND ADAPTIVE ORCHESTRATION IN S-AI-GPT
null (2) bgfbg bfgb bfgb fbfg bfbgf b.pdf
Safety Seminar civil to be ensured for safe working.
Fundamentals of Mechanical Engineering.pptx
Visual Aids for Exploratory Data Analysis.pdf
Abrasive, erosive and cavitation wear.pdf
AUTOMOTIVE ENGINE MANAGEMENT (MECHATRONICS).pptx
Module 8- Technological and Communication Skills.pptx
Management Information system : MIS-e-Business Systems.pptx
Soil Improvement Techniques Note - Rabbi
III.4.1.2_The_Space_Environment.p pdffdf
introduction to high performance computing
BIO-INSPIRED ARCHITECTURE FOR PARSIMONIOUS CONVERSATIONAL INTELLIGENCE : THE ...
Design Guidelines and solutions for Plastics parts
Unit I ESSENTIAL OF DIGITAL MARKETING.pdf
Occupational Health and Safety Management System

The Mayans Lost Guide to RxJava on Android

  • 4. #Reactive 1- of, relating to, or marked by reaction or reactance. 2- readily responsive to a stimulus.
  • 5. RxJava is a Java VM implementation of Reactive X (Reactive Extensions): ˝ a library for composing asynchronous and event-based programs by using observable sequences. What is RxJava?
  • 7. Multithreading is always complex˝ Concurrency˝ Java Futures are Expensive to Compose˝ Java Futures˝ Callbacks Have Their Own Problems˝ Callbacks˝ @benjchristensen from @netflix
  • 8. public class FuturesA { public static void run() throws Exception { ExecutorService executor = new ThreadPoolExecutor(4, 4, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>()); Future<String> f1 = executor.submit(new CallToRemoteServiceA()); Future<String> f2 = executor.submit(new CallToRemoteServiceB()); System.out.println(f1.get() + " - " + f2.get()); } } https://gist.github.com/benjchristensen/4670979 #Java Futures
  • 9. #Java Futures https://gist.github.com/benjchristensen/4671081 public static void run() throws Exception { ExecutorService executor = new ThreadPoolExecutor(4, 4, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>()); try { // get f3 with dependent result from f1 Future<String> f1 = executor.submit(new CallToRemoteServiceA()); Future<String> f3 = executor.submit(new CallToRemoteServiceC(f1.get())); /* The work below can not proceed until f1.get() completes even though there is no dependency */ // also get f4/f5 after dependency f2 completes Future<Integer> f2 = executor.submit(new CallToRemoteServiceB()); Future<Integer> f4 = executor.submit(new CallToRemoteServiceD(f2.get())); Future<Integer> f5 = executor.submit(new CallToRemoteServiceE(f2.get())); System.out.println(f3.get() + " => " + (f4.get() * f5.get())); } finally { executor.shutdownNow(); } }
  • 10. #Java Futures https://gist.github.com/benjchristensen/4671081 public static void run4() throws Exception { ExecutorService executor = new ThreadPoolExecutor(4, 4, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>()); try { List<Future<?>> futures = new ArrayList<Future<?>>(); // kick off several async tasks futures.add(executor.submit(new CallToRemoteServiceA())); futures.add(executor.submit(new CallToRemoteServiceB())); futures.add(executor.submit(new CallToRemoteServiceC("A"))); futures.add(executor.submit(new CallToRemoteServiceC("B"))); futures.add(executor.submit(new CallToRemoteServiceD(1))); futures.add(executor.submit(new CallToRemoteServiceE(2))); futures.add(executor.submit(new CallToRemoteServiceE(3))); // as each completes do further work for (Future<?> f : futures) { /* this blocks so even if other futures in the list complete earlier they will wait until this one is done */ doMoreWork(f.get()); } } finally { executor.shutdownNow(); } }
  • 11. Multithreading is always complex˝ Concurrency˝ Java Futures are Expensive to Compose˝ Java Futures˝ Callbacks Have Their Own Problems˝ Callbacks˝ @benjchristensen from @netflix
  • 12. #Callbacks https://gist.github.com/benjchristensen/4677544 ... // get f3 with dependent result from f1 executor.execute(new CallToRemoteServiceA(new Callback<String>() { @Override public void call(String f1) { executor.execute(new CallToRemoteServiceC(new Callback<String>() { @Override public void call(String f3) { // we have f1 and f3 now need to compose with others System.out.println("intermediate callback: " + f3 + " => " + ("f4 * f5")); // set to thread-safe variable accessible by external scope f3Value.set(f3); latch.countDown(); } }, f1)); } })); ...
  • 14. Observables The Observable object is who does the job. Represents an object that sends notifications (Provider) to a Subscriptor (Observer).
  • 15. Observables Add 2 missing semantics to the Observer pattern: #1: Emits a signal to the consumer when there is no more data available. #2: Emits a signal to the consumer when an error has occurred.
  • 18. Subscribers Subscribers provides a mechanism for receiving push- based notifications from Observables, and permits manual unsubscribing from these Observables.
  • 19. Subscribers Not an observer pattern: Observables often don't start emitting items until someone explicitly subscribes to them.
  • 20. Subscribers Observables often don't start emitting items until someone explicitly subscribes to them.
  • 21. Subscribers public class DefaultSubscriber<T> extends rx.Subscriber<T> { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(T t) { } }
  • 22. Subscriptions Subscriptions represents the link between your Observable and your Subscriber. #1: Subscriptions #2: CompositeSubscriptions
  • 23. #1: Schedulers.io() #2: Schedulers.computation() #3: Schedulers.from() Schedulers If you want to introduce multithreading into your cascade of Observable operators, you can do so by instructing those operators (or particular Observables) to operate on particular Schedulers.
  • 24. Operators Operators can be used in between the source Observable and the ultimate Subscriber to manipulate emitted items. You can even write your own custom operators.
  • 25. map() Transform the items emitted by an Observable by applying a function to each item.
  • 26. flatMap() Transforms the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable (no order)
  • 27. concatMap() Transforms the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable (keeps order)
  • 29. filter() Emits the same item it received, but only if it passes the boolean check (predicate).
  • 30. take() Emit only the first n items emitted by an Observable
  • 31. doOnNext() Allows us to add extra behavior each time an item is emitted.
  • 32. onError() is called if an exception is thrown at any time. Error handling The operators do not have to handle the exception.
  • 33. onErrorResumeNext() Instructs an Observable to emit a sequence of items if it encounters an error. onErrorReturn() Instructs an Observable to emit a particular item when it encounters an error. onExceptionResumeNext() Instructs an Observable to continue emitting items after it encounters an exception. retry() If a source Observable emits an error, resubscribe to it in the hopes that it will complete without error. retryWhen() If a source Observable emits an error, pass that error to another Observable to determine whether to resubscribe to the source. Error handling Operators
  • 34. #1: Observable and Subscriber can do anything #2: The Observable and Subscriber are independent of the transformational steps in between them. #3: Operators let you do anything to the stream of data. Key ideas behind RxJava http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/
  • 35. #1: Learning curve #2: Too many anonymous classes generated (OutOfMemory?) #3: Verbosity (retrolambda to the rescue?) But there are some pitfalls…
  • 38. @PerActivity public class UserListPresenter extends DefaultSubscriber<List<User>> implements Presenter { private UserListView viewListView; private final UseCase getUserListUseCase; @Inject public UserListPresenter(@Named("userList") UseCase getUserListUserCase, UserModelDataMapper userModelDataMapper) { this.getUserListUseCase = getUserListUserCase; } @Override public void destroy() { this.getUserListUseCase.unsubscribe(); } private void getUserList() { this.getUserListUseCase.execute(this); } ... } #Example: Reactive Presenter
  • 39. #Example: Reactive Presenter @PerActivity public class UserListPresenter extends DefaultSubscriber<List<User>> implements Presenter { ... @Override public void onCompleted() { this.hideViewLoading(); } @Override public void onError(Throwable e) { this.hideViewLoading(); this.showErrorMessage(new DefaultErrorBundle((Exception) e)); this.showViewRetry(); } @Override public void onNext(List<User> users) { this.showUsersCollectionInView(users); } }
  • 41. #Example: UseCase public abstract class UseCase { private final ThreadExecutor threadExecutor; private final PostExecutionThread postExecutionThread; private Subscription subscription = Subscriptions.empty(); protected UseCase(ThreadExecutor threadExecutor, PostExecutionThread postExecutionThread) { this.threadExecutor = threadExecutor; this.postExecutionThread = postExecutionThread; } protected abstract Observable buildUseCaseObservable(); public void execute(Subscriber UseCaseSubscriber) { this.subscription = this.buildUseCaseObservable() .subscribeOn(Schedulers.from(threadExecutor)) .observeOn(postExecutionThread.getScheduler()) .subscribe(UseCaseSubscriber); } public void unsubscribe() { if (!subscription.isUnsubscribed()) subscription.unsubscribe(); } }
  • 42. #Example: Execution Thread /** * MainThread (UI Thread) implementation based on a * {@link rx.Scheduler} which will execute actions on * the Android UI thread */ @Singleton public class UIThread implements PostExecutionThread { @Inject public UIThread() {} @Override public Scheduler getScheduler() { return AndroidSchedulers.mainThread(); } }
  • 43. #Example: UseCase /** * This class is an implementation of {@link UseCase} that represents a * use case for retrieving a collection of all {@link User}. */ public class GetUserListUseCase extends UseCase { private final UserRepository userRepository; @Inject public GetUserListUseCase(UserRepository userRepository, ThreadExecutor threadExecutor, PostExecutionThread postExecutionThread) { super(threadExecutor, postExecutionThread); this.userRepository = userRepository; } @Override public Observable buildUseCaseObservable() { return this.userRepository.getUsers(); } }
  • 45. #Example: Operator and Action public class CloudUserDataStore implements UserDataStore { private final RestApi restApi; private final UserCache userCache; private final Action1<UserEntity> saveToCacheAction = new Action1<UserEntity>() { @Override public void call(UserEntity userEntity) { if (userEntity != null) { CloudUserDataStore.this.userCache.put(userEntity); } } }; public CloudUserDataStore(RestApi restApi, UserCache userCache) { this.restApi = restApi; this.userCache = userCache; } @Override public Observable<List<UserEntity>> getUserEntityList() { return this.restApi.getUserEntityList(); } @Override public Observable<UserEntity> getUserEntityDetails(final int userId) { return this.restApi.getUserEntityById(userId).doOnNext(saveToCacheAction); } }
  • 46. #Example: Data transformation @Singleton public class UserDataRepository implements UserRepository { private final UserDataStoreFactory userDataStoreFactory; private final UserEntityDataMapper userEntityDataMapper; private final Func1<List<UserEntity>, List<User>> userListEntityMapper = new Func1<List<UserEntity>, List<User>>() { @Override public List<User> call(List<UserEntity> userEntities) { return UserDataRepository.this.userEntityDataMapper.transform(userEntities); } }; private final Func1<UserEntity, User> userDetailsEntityMapper = new Func1<UserEntity, User>() { @Override public User call(UserEntity userEntity) { return UserDataRepository.this.userEntityDataMapper.transform(userEntity); } }; @Override public Observable<List<User>> getUsers() { final UserDataStore userDataStore = this.userDataStoreFactory.createCloudDataStore(); return userDataStore.getUserEntityList().map(userListEntityMapper); } }
  • 47. #Example: Observable creation @Override public Observable<List<UserEntity>> getUserEntityList() { return Observable.create(new Observable.OnSubscribe<List<UserEntity>>() { @Override public void call(Subscriber<? super List<UserEntity>> subscriber) { if (isThereInternetConnection()) { try { String responseUserEntities = getUserEntitiesFromApi(); subscriber.onNext(userEntityJsonMapper.transformUserEntityCollection( responseUserEntities)); subscriber.onCompleted(); } catch (Exception e) { subscriber.onError(new NetworkConnectionException(e.getCause())); } } else { subscriber.onError(new NetworkConnectionException()); } } }); }
  • 48. #1: Good starting point to switch to Rx Observables. #2: No need to deal with threading an synchronization. #3: Very simple to wrap an http connection in an Observable How do I start with RxJava? Rx at data level
  • 49. #1: We can convert our events into Rx Observables How do I start with RxJava? Rx at view level Observable input = Observable.FromEventPattern(textView, "TextChanged") .Select(_ => textbox.Text) .Throttle(TimeSpan.FromSeconds(0.5)) .DistinctUntilChanged();
  • 50. #1: You will return Rx Observables in domain layer. #2: Be careful with side effects (Rx Schedulers other than UI Thread) How do I start with RxJava? Rx at domain level
  • 51. #1: By default, RxJava is synchronous. #2: onSubscribe() is executed separately for every new subscriber. #3: Subscriptions leak memory. Tips and Tricks #4: Read the official documentation
  • 52. References Reactive Programming on Android With RxJava https://mttkay.github.io/blog/2013/08/25/functional-reactive-programming-on-android-with-rxjava/ Grokking RxJava http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/ Reactive Programming in the Netflix API with RxJava http://techblog.netflix.com/2013/02/rxjava-netflix-api.html Rx for .NET and RxJava for Android http://futurice.com/blog/tech-pick-of-the-week-rx-for-net-and-rxjava-for-android https://github.com/android10/Android-CleanArchitecture Official Documentation https://github.com/ReactiveX/RxJava/wiki https://github.com/android10/Android-ReactiveProgramming
  • 53. ?˝ Source: US Census Bureau Questions