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.
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.
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)
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…
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();
}
}
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