SlideShare a Scribd company logo
1 of 68
Download to read offline
What it means to be Reactive?
RxJava for Android
Constantine Mars
Senior Android Developer @ DataArt
GDG Dnipro and JUG Dnepr
–Ivan Morgillo, Alter Ego solutions, speech on DroidCon Berlin’2015
“A piece of cake, you know”
#dfua
Faces of the Reactive Programming World
Ben Christensen, Netflix - RxJava
Erik Meijer, Applied Duality - Rx.NET
Jake Wharton, Square - RxAndroid
Ivan Morgillo, Alter Ego - first book
about RxAndroid
Fundamentals
The basic concepts behind Rx
#dfua
Time to meditate...
Everything is a stream…
#dfua
The one who is listening is Observer
And the other one, who is emitting events, is Subject, or Observable
*Illustration from O’Reilly® HeadFirst “Design Patterns” book:
#dfua
This is well known interface in for both Android and Desktop developers
Observer = Listener
t.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Timber.d("something");
}
});
.JAVA
#dfua
We will use it throughout presentation
Lambda syntax
t.setOnClickListener(v -> Timber.d("something"));
.JAVA
RxJava. Observable & Observer
Basics
#dfua
It’s the source of events
Observable
rx.Observable<Integer> observable = rx.Observable.create(
new rx.Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
for (int i = 0; i < N; i++) {
Integer integer = random.nextInt(MAX);
subscriber.onNext(integer);
}
subscriber.onCompleted();
}
});
.JAVA
Be aware: there is java.util.Observable besides rx.Observable - they’re not the same
#dfua
It’s the source of events. It handles subscriptions through OnSubscribe callback
Observable
rx.Observable<Integer> observable = rx.Observable.create(
new rx.Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
for (int i = 0; i < N; i++) {
Integer integer = random.nextInt(MAX);
subscriber.onNext(integer);
}
subscriber.onCompleted();
}
});
.JAVA
Be aware: there is java.util.Observable besides rx.Observable - they’re not the same
#dfua
It’s the source of events. It handles subscriptions through OnSubscribe callback.
When observer subscribes, it is named subscriber inside of a call()
Observable
rx.Observable<Integer> observable = rx.Observable.create(
new rx.Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
for (int i = 0; i < N; i++) {
Integer integer = random.nextInt(MAX);
subscriber.onNext(integer);
}
subscriber.onCompleted();
}
});
.JAVA
Be aware: there is java.util.Observable besides rx.Observable - they’re not the same
#dfua
It’s the source of events. It handles subscriptions through OnSubscribe callback.
When observer subscribes, it is named subscriber inside of a call()
Observable
rx.Observable<Integer> observable = rx.Observable.create(
new rx.Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
for (int i = 0; i < N; i++) {
Integer integer = random.nextInt(MAX);
subscriber.onNext(integer);
}
subscriber.onCompleted();
}
});
.JAVA
Be aware: there is java.util.Observable besides rx.Observable - they’re not the same
#dfua
Observer
rx.Observer<Integer> observer = new rx.Observer<Integer>() {
@Override
public void onCompleted() {
display.show("completed");
}
@Override
public void onError(Throwable e) {
display.show("error: " + e.getMessage());
}
@Override
public void onNext(Integer integer) {
display.show("next: " + integer);
}
};
observable.subscribe(observer);
.JAVA
It’s the bunch of Reactive callbacks that should be registered through
subscription.
#dfua
It’s the bunch of Reactive callbacks that should be registered through
subscription. And handles incoming onNext(), onCompleted() and onError() from
Observable
Observer
rx.Observer<Integer> observer = new rx.Observer<Integer>() {
@Override
public void onCompleted() {
display.show("completed");
}
@Override
public void onError(Throwable e) {
display.show("error: " + e.getMessage());
}
@Override
public void onNext(Integer integer) {
display.show("next: " + integer);
}
};
observable.subscribe(observer);
.JAVA
#dfua
But to make magic we need one more thing...
Observer
rx.Observer<Integer> observer = new rx.Observer<Integer>() {
@Override
public void onCompleted() {
display.show("completed");
}
@Override
public void onError(Throwable e) {
display.show("error: " + e.getMessage());
}
@Override
public void onNext(Integer integer) {
display.show("next: " + integer);
}
};
observable.subscribe(observer);
.JAVA
#dfua
To subscribe. This means creating Subscription.
Subscription
Subscription subscription = observable.subscribe(observer);
...
if(!subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
.JAVA
#dfua
To subscribe. This means creating Subscription.
In fact Subscription class is rarely used, but can be useful to unsubscribe when we
don’t need to receive events
Subscription
Subscription subscription = observable.subscribe(observer);
...
if(!subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
.JAVA
#dfua
Looks more readable, isn’t it?
At least takes one screen, not three :)
Observable + Observer with lambdas
rx.Observable<Integer> observable = rx.Observable.create(subscriber -> {
for (int i = 0; i < N; i++)
subscriber.onNext(random.nextInt(MAX));
subscriber.onCompleted();
});
observable.subscribe(
integer -> display.show("next: " + integer),
throwable -> display.show("error: " + throwable.getMessage()),
() -> display.show("completed"));
.JAVA
#dfua
Reactive Systems are:
*Check ReactiveManifesto.org for detailed definitions:
Message Driven
Responsive
Resilient
Scalable (Elastic)
From everything, ...even from air :)
Creating Observables
#dfua
Observable.from()
ENTER FILENAME/LANG
ArrayList<Integer> arrayList = new ArrayList<>();
int MAX_N = random.nextInt(12) + 5;
for (int i = 0; i < MAX_N; i++) arrayList.add(random.nextInt(MAX));
rx.Observable.from(arrayList)
.subscribe(
integer -> display.show("next: " + integer),
throwable -> display.show("error: " + throwable.getMessage()),
() -> display.show("complete"));
.JAVA
#dfua
Observable.just()
ENTER FILENAME/LANG
private List<Integer> generate() {
Random r = new Random();
int n = r.nextInt(5) + 5;
ArrayList<Integer> a = new ArrayList<>();
for (int i = 0; i < n; i++)
a.add(r.nextInt(100));
return a;
}
public void just() {
rx.Observable.just(generate())
.subscribe(integer -> display.show("next: " + integer),
throwable -> display.show("error: " + throwable.getMessage()),
() -> display.show("complete"));
}
.JAVA
#dfua
Observable.interval()
Random r = new Random();
rx.Observable.interval(2, TimeUnit.SECONDS)
.map(t -> new long[]{t, r.nextInt(100)})
.limit(5)
.subscribe(
tuple -> display.show("next: " + Arrays.toString(tuple)),
throwable -> {
},
() -> display.show("complete"));
.JAVA
#dfua
Retrofit
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("https://api.github.com")
.build();
GitHubService service = restAdapter.create(GitHubService.class);
// Retrofit can return observable which we handle as any other observable
service.listRepos("c-mars")
.flatMap(Observable::from)
.limit(10)
.subscribe(repo -> display.show("next: " + repo.toString()),
throwable -> display.show("error: " + throwable.getMessage()),
() -> display.show("completed"));
.JAVA
#dfua
RxBindings
Button button;
...
RxView.clicks(button)
.map(v -> ++counter)
.debounce(500, TimeUnit.MILLISECONDS)
.subscribe(c -> display.show("button " + c));
.JAVA
Filtering, conditions
RxJava Goods
#dfua
Blocking
private final AmmeterReadings[] data = {
new AmmeterReadings(1, 0.5),
...
};
private static float getMaxValue(AmmeterReadings[] data) {
return MathObservable.max(rx.Observable.from(data)
.map(AmmeterReadings::getCurrent))
.toBlocking().firstOrDefault(0L);
}
.JAVA
By default rx.Observable is async. But it can be converted to BlockingObservable
and return result in-place, using functional computations.
#dfua
first, last, take, orDefault
private final AmmeterReadings[] data = {
new AmmeterReadings(1, 0.5),
...
};
private static float getMaxValue(AmmeterReadings[] data) {
return MathObservable.max(rx.Observable.from(data)
.map(AmmeterReadings::getCurrent))
.toBlocking().firstOrDefault(0L);
}
.JAVA
We can take first, last or any item from BlockingObservable. If it’s empty, we can
define default value.
#dfua
take from Observable
private final AmmeterReadings[] data = {
new AmmeterReadings(1, 0.5),
...
};
private static float getMaxValue(AmmeterReadings[] data) {
return MathObservable.max( rx.Observable.from(data)
.map(AmmeterReadings::getCurrent)
.takeLast(5) )
.toBlocking().firstOrDefault(0L);
}
.JAVA
rx.Observable (non-blocking) provides method take() to take multiple items from
stream.
#dfua
singleOrDefault
rx.Observable.range(0, 0)
.singleOrDefault(-1)
.forEach(i -> getDisplay().show("single:" + i));
.JAVA
Check whether rx.Observable contains only one event/item.
#dfua
defaultIfEmpty
rx.Observable.range(0, max)
.defaultIfEmpty(999)
.forEach(i -> getDisplay().show("range 0->" + max + ", value (999 if empty):"
+ String.valueOf(i)));
.JAVA
Almost the same as singleOrDefault
#dfua
toIterable
final Integer[] data = {200, 4, 145, -1, 10, -12, 80};
Iterable<Integer> iterable = rx.Observable.from(data)
.toBlocking().toIterable();
for (Integer i : iterable) {
display.show("iterable:" + i.toString());
}
.JAVA
BlockingObservable.toIterable() converts rx.Observable to collection
#dfua
forEach
final Integer[] data = {200, 4, 145, -1, 10, -12, 80};
rx.Observable.from(data)
.forEach(i -> display.show("iterable:" + i.toString()));
.JAVA
forEach() is just shorcut to .subscribe()
#dfua
takeUntil
rx.Observable.range(0, 10)
.takeUntil(i -> i == 5)
.forEach(i -> getDisplay().show(String.valueOf(i)));
// out: 0, 1, 2, 3, 4, 5
.JAVA
Just a variant of take(), which completes when condition matches.
#dfua
contains
rx.Observable.range(0, max)
.contains(2)
.forEach(i -> getDisplay().show("range: " + 0 + "->" + max + ",contains 2: " +
String.valueOf(i)));
// out: true (or false)
.JAVA
Check whether stream contains certain value
#dfua
filter
rx.Observable.range(0, 10)
.filter(i -> i > 5 && i < 9 )
.forEach(i -> getDisplay().show(i));
// out: 6, 7, 8
.JAVA
Like takeUntil, just filter :)
#dfua
debounce
long[] times = {3, 2, 1, 5, 2, 6};
rx.Observable<Pair<Integer, Long>> observable = rx.Observable.create(subscriber -> {
int sz = times.length;
for (int i = 0; i < sz; i++) {
try {
long t = times[i];
TimeUnit.MILLISECONDS.sleep(t);
subscriber.onNext(new Pair<>(i, t));
} catch (InterruptedException e) {
subscriber.onError(e);
}
}
subscriber.onCompleted();
});
observable.debounce(4, TimeUnit.MILLISECONDS)
.subscribe(pair -> getDisplay().show("out: value=" + pair.first + ", time=" +
pair.second));
.JAVA
#dfua
sample
long[] times = {3, 2, 1, 5, 4, 3, 1};
rx.Observable<Pair<Integer, Long>> observable = rx.Observable.create(subscriber -> {
int sz = times.length;
for (int i = 0; i < sz; i++) {
try {
long t = times[i];
TimeUnit.MILLISECONDS.sleep(t * 10);
subscriber.onNext(new Pair<>(i, t));
} catch (InterruptedException e) {
subscriber.onError(e);
}
}
subscriber.onCompleted();
});
observable.sample(40, TimeUnit.MILLISECONDS)
.subscribe(pair -> getDisplay().show("out: value=" + pair.first + "; time=" +
pair.second));
.JAVA
Merge and combine
RxJava Goods
#dfua
merge
rx.Observable first = Observable.range(0, 5); //int[]
rx.Observable second = Observable.from(new String[]{"one", "two", "three", "four",
"five"}); //String[]
rx.Observable.merge(first, second)
.forEach(item -> getDisplay().show(item.toString()));
.JAVA
Merges items from separate rx.Observables to single stream
#dfua
zip
rx.Observable<Integer> first = Observable.range(0, 5); //int[]
rx.Observable<String> second = Observable.from(new String[]{"one", "two",
"three", "four", "five"}); //String[]
rx.Observable.zip(first, second, (i, s) -> new Pair(s, i))
.forEach(pair -> getDisplay().show(pair.toString()));
.JAVA
Merges items from separate rx.Observables to single stream using combining
function.
RxJava Error Handling
#dfua
retry
rx.Observable<Integer> canFail = rx.Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
for (int i = 0; i < 6; i++) {
switch (i) {
case 3:
if (!failedOnce) {
failedOnce = true;
subscriber.onError(new Error());
return;
}
break;
case 5:
subscriber.onError(new Throwable());
return;
}
subscriber.onNext(i);
}
subscriber.onCompleted();
}
});
.JAVA
#dfua
retry
canFail.retry((integer, throwable) -> {
boolean retry = (throwable instanceof Error);
getDisplay().show("retry, errors: " + integer);
return retry;
})
.subscribe(i -> {
getDisplay().show(i);
}, throwable -> {
getDisplay().show("error: " + throwable.getMessage());
});
.JAVA
#dfua
retry
In case of error we can check condition in retry() and then
re-subscribe and try once more
Math and aggregate
RxJava Goods
#dfua
MathObservable
private final AmmeterReadings[] data = {
new AmmeterReadings(1, 0.5),
...
};
private static float getMaxValue(AmmeterReadings[] data) {
return MathObservable.max(rx.Observable.from(data)
.map(AmmeterReadings::getCurrent))
.toBlocking().firstOrDefault(0L);
}
.JAVA
Plugin MathObservable: compile 'io.reactivex:rxjava-math:1.0.0'
max, average, sum, count
#dfua
Average
rx.Observable<Integer> integers = rx.Observable.range(0, 10);
MathObservable.averageInteger(integers).subscribe(avg -> {
getDisplay().show(avg);
});
.JAVA
Many methods of MathObservable has type-aware alternatives
#dfua
reduce
rx.Observable.range(0, 10).reduce((a, b) -> {
int c = a + b;
getDisplay().show("reduce: a=" + a + " + " + b + " = " + c);
return c;
}).forEach(value -> getDisplay().show("result: " + value));
.JAVA
Classic reduce operation, common for all functional programming languages
Ubiquitous mediums that like actors can play any role
RxJava Subjects
#dfua
Creating Subjects
PublishSubject<String> subject = PublishSubject.create();
example(subject);
…
ReplaySubject<String> subject = ReplaySubject.createWithSize(2);
example(subject);
.JAVA
Subjects have method .create() for this. ReplaySubject can also be created with
predefined number of events to replay on subscription.
#dfua
Example code
private void example(Subject<String, String> subject) {
subject.onNext("before 1");
subject.onNext("before 2");
subject.onNext("before 3");
subject.onNext("before 4");
subject.subscribe(s -> getDisplay().show("subscribed: " + s));
subject.onNext("after 5");
subject.onNext("after 6");
subject.onNext("after 7");
subject.onNext("after 8");
subject.onCompleted();
}
.JAVA
Subject can act both like Observable and Observer. So we can call .onNext,
.onComplete manually and trigger subscription callbacks
#dfua
Subjects behaviour
PublishSubject
Is just a proxy for events
AsyncSubject
Replays only last event onComplete
ReplaySubject
Replays last N events and
then proxies the same as
Publish
BehaviorSubject
Replays only last event and
then proxies the same as
Publish
#dfua
ReactiveX Diagrams
In a hour of despair - seek inspiration at ReactiveX.io
RxJava Schedulers
#dfua
Schedulers
rx.Observable.from(readFromFile(context))
.subscribeOn(Schedulers.io())
.forEach(line -> textView.append("n" + line));
.JAVA
By default rx.Observable is single-threaded. Here come Schedulers to hide
threading and synchronization behind the functional interface.
Just call .subscribeOn() and define which kind of threading you want
#dfua
Schedulers
rx.Observable source = rx.Observable.range(0, 10).map(integer -> {
List<Integer> outs = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
for (int j = 0; j < 1000; j++) {
outs.add((int) Math.pow(i, j));
}
}
return outs;
}).flatMap(Observable::from);
MathObservable.sumInteger(source)
.subscribeOn(Schedulers.computation())
.subscribe(integer -> textView.setText("final sum: " + integer.toString()));
.JAVA
#dfua
Android UI
MathObservable.sumInteger(source)
.subscribeOn(Schedulers.computation())
.subscribe(integer -> textView.setText("final sum: " + integer.toString()));
.JAVA
Scheduler move execution to another appropriate thread. But when we try to
update UI from this chain - something bad happens...
#dfua
Android UI
MathObservable.sumInteger(source)
.subscribeOn(Schedulers.computation())
.subscribe(integer -> textView.setText("final sum: " + integer.toString()));
.JAVA
Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the
original thread that created a view hierarchy can touch its views.
E/AndroidRuntime: at
android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6556)
E/AndroidRuntime: at
android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:942)
E/AndroidRuntime: at android.view.ViewGroup.invalidateChild(ViewGroup.java:5081)
E/AndroidRuntime: at android.view.View.invalidateInternal(View.java:12713)
E/AndroidRuntime: at android.view.View.invalidate(View.java:12677)
E/AndroidRuntime: at android.view.View.invalidate(View.java:12661)
...
CONSOLE
Comes to play
RxAndroid
#dfua
Relationship to RxJava
#dfua
AndroidSchedulers
rx.Observable.from(readFromFile(context))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.forEach(line -> textView.append("n" + line));
.JAVA
.subscribeOn defines thread on which computations run,
.observeOn defines thread on which rx.Observer callbacks will run
#dfua
Activity Lifecycle
// Activity
private Subscription subscription;
protected void onCreate(Bundle savedInstanceState) {
this.subscription = observable.subscribe(this);
}
...
protected void onDestroy() {
this.subscription.unsubscribe();
super.onDestroy();
}
.JAVA
Use subscription or CompositeSubscription
RxJava
Journey comes to end
#dfua
Where to look?
● JavaDoc: http://reactivex.io/RxJava/javadoc/rx/Observable.html
● List of Additional Reading from RxJava Wiki:
https://github.com/ReactiveX/RxJava/wiki/Additional-Reading
● RxJava Essentials by Ivan Morgillo:
https://www.packtpub.com/application-development/rxjava-essentials
● RxMarbles - interactive diagrams: http://rxmarbles.com/
#dfua
ReactiveX RxJava Additional Reading
Thank you!
Questions?
+ConstantineMars
dataart.com.ua
dnipro.gdg.org.ua

More Related Content

What's hot

An Introduction to RxJava
An Introduction to RxJavaAn Introduction to RxJava
An Introduction to RxJavaSanjay Acharya
 
Reactive programming with RxJava
Reactive programming with RxJavaReactive programming with RxJava
Reactive programming with RxJavaJobaer Chowdhury
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaFabio Collini
 
Introduction to RxJava on Android
Introduction to RxJava on AndroidIntroduction to RxJava on Android
Introduction to RxJava on AndroidChris Arriola
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJSBrainhub
 
Streams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to RxStreams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to RxAndrzej Sitek
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaRick Warren
 
My Gentle Introduction to RxJS
My Gentle Introduction to RxJSMy Gentle Introduction to RxJS
My Gentle Introduction to RxJSMattia Occhiuto
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on AndroidTomáš Kypta
 
Rxjava 介紹與 Android 中的 RxJava
Rxjava 介紹與 Android 中的 RxJavaRxjava 介紹與 Android 中的 RxJava
Rxjava 介紹與 Android 中的 RxJavaKros Huang
 
RxJava 2.0 介紹
RxJava 2.0 介紹RxJava 2.0 介紹
RxJava 2.0 介紹Kros Huang
 
RxJava from the trenches
RxJava from the trenchesRxJava from the trenches
RxJava from the trenchesPeter Hendriks
 

What's hot (20)

RxJava@Android
RxJava@AndroidRxJava@Android
RxJava@Android
 
An Introduction to RxJava
An Introduction to RxJavaAn Introduction to RxJava
An Introduction to RxJava
 
Reactive programming with RxJava
Reactive programming with RxJavaReactive programming with RxJava
Reactive programming with RxJava
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJava
 
Reactive Java (33rd Degree)
Reactive Java (33rd Degree)Reactive Java (33rd Degree)
Reactive Java (33rd Degree)
 
Introduction to RxJava on Android
Introduction to RxJava on AndroidIntroduction to RxJava on Android
Introduction to RxJava on Android
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
Streams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to RxStreams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to Rx
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
 
My Gentle Introduction to RxJS
My Gentle Introduction to RxJSMy Gentle Introduction to RxJS
My Gentle Introduction to RxJS
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
RxJava in practice
RxJava in practice RxJava in practice
RxJava in practice
 
Reactive Java (GeeCON 2014)
Reactive Java (GeeCON 2014)Reactive Java (GeeCON 2014)
Reactive Java (GeeCON 2014)
 
Rxjava 介紹與 Android 中的 RxJava
Rxjava 介紹與 Android 中的 RxJavaRxjava 介紹與 Android 中的 RxJava
Rxjava 介紹與 Android 中的 RxJava
 
RxJava 2.0 介紹
RxJava 2.0 介紹RxJava 2.0 介紹
RxJava 2.0 介紹
 
RxJava Applied
RxJava AppliedRxJava Applied
RxJava Applied
 
rx-java-presentation
rx-java-presentationrx-java-presentation
rx-java-presentation
 
Rx java in action
Rx java in actionRx java in action
Rx java in action
 
RxJava from the trenches
RxJava from the trenchesRxJava from the trenches
RxJava from the trenches
 
Introduction to Reactive Java
Introduction to Reactive JavaIntroduction to Reactive Java
Introduction to Reactive Java
 

Viewers also liked

RxJava for Android - GDG and DataArt
RxJava for Android - GDG and DataArtRxJava for Android - GDG and DataArt
RxJava for Android - GDG and DataArtConstantine Mars
 
The Mayans Lost Guide to RxJava on Android
The Mayans Lost Guide to RxJava on AndroidThe Mayans Lost Guide to RxJava on Android
The Mayans Lost Guide to RxJava on AndroidFernando Cejas
 
RxJava on Android
RxJava on AndroidRxJava on Android
RxJava on Androidyo_waka
 
Introduction to rx java for android
Introduction to rx java for androidIntroduction to rx java for android
Introduction to rx java for androidEsa Firman
 
Rx Java architecture
Rx Java architectureRx Java architecture
Rx Java architecturee-Legion
 
Headless fragments in Android
Headless fragments in AndroidHeadless fragments in Android
Headless fragments in AndroidAli Muzaffar
 
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민 track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민 양 한빛
 
Java 8 Stream API and RxJava Comparison
Java 8 Stream API and RxJava ComparisonJava 8 Stream API and RxJava Comparison
Java 8 Stream API and RxJava ComparisonJosé Paumard
 
[메조미디어] 2017년 미디어트렌드리포트
[메조미디어] 2017년 미디어트렌드리포트[메조미디어] 2017년 미디어트렌드리포트
[메조미디어] 2017년 미디어트렌드리포트MezzoMedia
 

Viewers also liked (11)

2 презентация rx java+android
2 презентация rx java+android2 презентация rx java+android
2 презентация rx java+android
 
RxJava for Android - GDG and DataArt
RxJava for Android - GDG and DataArtRxJava for Android - GDG and DataArt
RxJava for Android - GDG and DataArt
 
The Mayans Lost Guide to RxJava on Android
The Mayans Lost Guide to RxJava on AndroidThe Mayans Lost Guide to RxJava on Android
The Mayans Lost Guide to RxJava on Android
 
Android concurrency
Android concurrencyAndroid concurrency
Android concurrency
 
RxJava on Android
RxJava on AndroidRxJava on Android
RxJava on Android
 
Introduction to rx java for android
Introduction to rx java for androidIntroduction to rx java for android
Introduction to rx java for android
 
Rx Java architecture
Rx Java architectureRx Java architecture
Rx Java architecture
 
Headless fragments in Android
Headless fragments in AndroidHeadless fragments in Android
Headless fragments in Android
 
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민 track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민
 
Java 8 Stream API and RxJava Comparison
Java 8 Stream API and RxJava ComparisonJava 8 Stream API and RxJava Comparison
Java 8 Stream API and RxJava Comparison
 
[메조미디어] 2017년 미디어트렌드리포트
[메조미디어] 2017년 미디어트렌드리포트[메조미디어] 2017년 미디어트렌드리포트
[메조미디어] 2017년 미디어트렌드리포트
 

Similar to RxJava for Android - GDG DevFest Ukraine 2015

响应式编程及框架
响应式编程及框架响应式编程及框架
响应式编程及框架jeffz
 
Tech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn Tới
Tech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn TớiTech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn Tới
Tech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn TớiNexus FrontierTech
 
WattGo: Analyses temps-réél de series temporelles avec Spark et Solr (Français)
WattGo: Analyses temps-réél de series temporelles avec Spark et Solr (Français)WattGo: Analyses temps-réél de series temporelles avec Spark et Solr (Français)
WattGo: Analyses temps-réél de series temporelles avec Spark et Solr (Français)DataStax Academy
 
RxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камниRxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камниStfalcon Meetups
 
RxJS Operators - Real World Use Cases - AngularMix
RxJS Operators - Real World Use Cases - AngularMixRxJS Operators - Real World Use Cases - AngularMix
RxJS Operators - Real World Use Cases - AngularMixTracy Lee
 
ReactiveCocoa in Practice
ReactiveCocoa in PracticeReactiveCocoa in Practice
ReactiveCocoa in PracticeOutware Mobile
 
RxJava2 Slides
RxJava2 SlidesRxJava2 Slides
RxJava2 SlidesYarikS
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on AndroidTomáš Kypta
 
rx.js make async programming simpler
rx.js make async programming simplerrx.js make async programming simpler
rx.js make async programming simplerAlexander Mostovenko
 
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...GeeksLab Odessa
 
4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...
4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...
4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...PROIDEA
 
Reactive Programming no Android
Reactive Programming no AndroidReactive Programming no Android
Reactive Programming no AndroidGuilherme Branco
 
Ft10 de smet
Ft10 de smetFt10 de smet
Ft10 de smetnkaluva
 
Reactive Thinking in iOS Development - Pedro Piñera Buendía - Codemotion Amst...
Reactive Thinking in iOS Development - Pedro Piñera Buendía - Codemotion Amst...Reactive Thinking in iOS Development - Pedro Piñera Buendía - Codemotion Amst...
Reactive Thinking in iOS Development - Pedro Piñera Buendía - Codemotion Amst...Codemotion
 

Similar to RxJava for Android - GDG DevFest Ukraine 2015 (20)

响应式编程及框架
响应式编程及框架响应式编程及框架
响应式编程及框架
 
Saving lives with rx java
Saving lives with rx javaSaving lives with rx java
Saving lives with rx java
 
Tech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn Tới
Tech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn TớiTech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn Tới
Tech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn Tới
 
Rxjs kyivjs 2015
Rxjs kyivjs 2015Rxjs kyivjs 2015
Rxjs kyivjs 2015
 
WattGo: Analyses temps-réél de series temporelles avec Spark et Solr (Français)
WattGo: Analyses temps-réél de series temporelles avec Spark et Solr (Français)WattGo: Analyses temps-réél de series temporelles avec Spark et Solr (Français)
WattGo: Analyses temps-réél de series temporelles avec Spark et Solr (Français)
 
Rxjs marble-testing
Rxjs marble-testingRxjs marble-testing
Rxjs marble-testing
 
RxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камниRxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камни
 
Iniciación rx java
Iniciación rx javaIniciación rx java
Iniciación rx java
 
RxJS Operators - Real World Use Cases - AngularMix
RxJS Operators - Real World Use Cases - AngularMixRxJS Operators - Real World Use Cases - AngularMix
RxJS Operators - Real World Use Cases - AngularMix
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
 
ReactiveCocoa in Practice
ReactiveCocoa in PracticeReactiveCocoa in Practice
ReactiveCocoa in Practice
 
RxJava2 Slides
RxJava2 SlidesRxJava2 Slides
RxJava2 Slides
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Rx – reactive extensions
Rx – reactive extensionsRx – reactive extensions
Rx – reactive extensions
 
rx.js make async programming simpler
rx.js make async programming simplerrx.js make async programming simpler
rx.js make async programming simpler
 
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
 
4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...
4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...
4Developers 2015: Programowanie synchroniczne i asynchroniczne - dwa światy k...
 
Reactive Programming no Android
Reactive Programming no AndroidReactive Programming no Android
Reactive Programming no Android
 
Ft10 de smet
Ft10 de smetFt10 de smet
Ft10 de smet
 
Reactive Thinking in iOS Development - Pedro Piñera Buendía - Codemotion Amst...
Reactive Thinking in iOS Development - Pedro Piñera Buendía - Codemotion Amst...Reactive Thinking in iOS Development - Pedro Piñera Buendía - Codemotion Amst...
Reactive Thinking in iOS Development - Pedro Piñera Buendía - Codemotion Amst...
 

More from Constantine Mars

Mobile Applications Architecture - GDG Ternopil' Architecture Components Meetup
Mobile Applications Architecture - GDG Ternopil' Architecture Components MeetupMobile Applications Architecture - GDG Ternopil' Architecture Components Meetup
Mobile Applications Architecture - GDG Ternopil' Architecture Components MeetupConstantine Mars
 
Quick look at Design Patterns in Android Development
Quick look at Design Patterns in Android DevelopmentQuick look at Design Patterns in Android Development
Quick look at Design Patterns in Android DevelopmentConstantine Mars
 
Dagger 2 - Ciklum Speakers' Corner
Dagger 2 - Ciklum Speakers' CornerDagger 2 - Ciklum Speakers' Corner
Dagger 2 - Ciklum Speakers' CornerConstantine Mars
 
Architecture components - IT Talk
Architecture components - IT TalkArchitecture components - IT Talk
Architecture components - IT TalkConstantine Mars
 
Jump into cross platform development with firebase
Jump into cross platform development with firebaseJump into cross platform development with firebase
Jump into cross platform development with firebaseConstantine Mars
 
Android Wear 2.0 - New Level of Freedom for Your Action - GDG CEE Leads Summi...
Android Wear 2.0 - New Level of Freedom for Your Action - GDG CEE Leads Summi...Android Wear 2.0 - New Level of Freedom for Your Action - GDG CEE Leads Summi...
Android Wear 2.0 - New Level of Freedom for Your Action - GDG CEE Leads Summi...Constantine Mars
 
Android Wear 2.0 - Great Changes Upcoming This Fall - GDG DevFest Ukraine 2016
Android Wear 2.0 - Great Changes Upcoming This Fall - GDG DevFest Ukraine 2016Android Wear 2.0 - Great Changes Upcoming This Fall - GDG DevFest Ukraine 2016
Android Wear 2.0 - Great Changes Upcoming This Fall - GDG DevFest Ukraine 2016Constantine Mars
 
Dagger2 - IT NonStop Voronezh 2016
Dagger2 - IT NonStop Voronezh 2016Dagger2 - IT NonStop Voronezh 2016
Dagger2 - IT NonStop Voronezh 2016Constantine Mars
 
DeviceHive Android BLE Gateway
DeviceHive Android BLE GatewayDeviceHive Android BLE Gateway
DeviceHive Android BLE GatewayConstantine Mars
 
Android Wear 2.0, Awareness API - GDG Dnipro Post I/O 2016
Android Wear 2.0, Awareness API - GDG Dnipro Post I/O 2016Android Wear 2.0, Awareness API - GDG Dnipro Post I/O 2016
Android Wear 2.0, Awareness API - GDG Dnipro Post I/O 2016Constantine Mars
 
Android Wear 2.0 - IT NonStop Dnipro
Android Wear 2.0 - IT NonStop DniproAndroid Wear 2.0 - IT NonStop Dnipro
Android Wear 2.0 - IT NonStop DniproConstantine Mars
 
Android N Security Overview - Mobile Security Saturday at Ciklum
Android N Security Overview - Mobile Security Saturday at CiklumAndroid N Security Overview - Mobile Security Saturday at Ciklum
Android N Security Overview - Mobile Security Saturday at CiklumConstantine Mars
 
Study Jam: Android for Beginners, Summary
Study Jam: Android for Beginners, SummaryStudy Jam: Android for Beginners, Summary
Study Jam: Android for Beginners, SummaryConstantine Mars
 

More from Constantine Mars (16)

Mobile Applications Architecture - GDG Ternopil' Architecture Components Meetup
Mobile Applications Architecture - GDG Ternopil' Architecture Components MeetupMobile Applications Architecture - GDG Ternopil' Architecture Components Meetup
Mobile Applications Architecture - GDG Ternopil' Architecture Components Meetup
 
Quick look at Design Patterns in Android Development
Quick look at Design Patterns in Android DevelopmentQuick look at Design Patterns in Android Development
Quick look at Design Patterns in Android Development
 
Dagger 2 - Ciklum Speakers' Corner
Dagger 2 - Ciklum Speakers' CornerDagger 2 - Ciklum Speakers' Corner
Dagger 2 - Ciklum Speakers' Corner
 
Architecture components - IT Talk
Architecture components - IT TalkArchitecture components - IT Talk
Architecture components - IT Talk
 
Jump into cross platform development with firebase
Jump into cross platform development with firebaseJump into cross platform development with firebase
Jump into cross platform development with firebase
 
Android Wear 2.0 - New Level of Freedom for Your Action - GDG CEE Leads Summi...
Android Wear 2.0 - New Level of Freedom for Your Action - GDG CEE Leads Summi...Android Wear 2.0 - New Level of Freedom for Your Action - GDG CEE Leads Summi...
Android Wear 2.0 - New Level of Freedom for Your Action - GDG CEE Leads Summi...
 
Android Wear 2.0 - Great Changes Upcoming This Fall - GDG DevFest Ukraine 2016
Android Wear 2.0 - Great Changes Upcoming This Fall - GDG DevFest Ukraine 2016Android Wear 2.0 - Great Changes Upcoming This Fall - GDG DevFest Ukraine 2016
Android Wear 2.0 - Great Changes Upcoming This Fall - GDG DevFest Ukraine 2016
 
Dagger2 - IT NonStop Voronezh 2016
Dagger2 - IT NonStop Voronezh 2016Dagger2 - IT NonStop Voronezh 2016
Dagger2 - IT NonStop Voronezh 2016
 
DeviceHive Android BLE Gateway
DeviceHive Android BLE GatewayDeviceHive Android BLE Gateway
DeviceHive Android BLE Gateway
 
Scrum Overview
Scrum OverviewScrum Overview
Scrum Overview
 
Android Wear 2.0, Awareness API - GDG Dnipro Post I/O 2016
Android Wear 2.0, Awareness API - GDG Dnipro Post I/O 2016Android Wear 2.0, Awareness API - GDG Dnipro Post I/O 2016
Android Wear 2.0, Awareness API - GDG Dnipro Post I/O 2016
 
Android Wear 2.0 - IT NonStop Dnipro
Android Wear 2.0 - IT NonStop DniproAndroid Wear 2.0 - IT NonStop Dnipro
Android Wear 2.0 - IT NonStop Dnipro
 
Android N Security Overview - Mobile Security Saturday at Ciklum
Android N Security Overview - Mobile Security Saturday at CiklumAndroid N Security Overview - Mobile Security Saturday at Ciklum
Android N Security Overview - Mobile Security Saturday at Ciklum
 
Study Jam: Android for Beginners, Summary
Study Jam: Android for Beginners, SummaryStudy Jam: Android for Beginners, Summary
Study Jam: Android for Beginners, Summary
 
Pebble Watch Development
Pebble Watch DevelopmentPebble Watch Development
Pebble Watch Development
 
Xamarin Forms in Action
Xamarin Forms in ActionXamarin Forms in Action
Xamarin Forms in Action
 

Recently uploaded

Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slidesvaideheekore1
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogueitservices996
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLionel Briand
 
2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shardsChristopher Curtin
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITmanoharjgpsolutions
 
Not a Kubernetes fan? The state of PaaS in 2024
Not a Kubernetes fan? The state of PaaS in 2024Not a Kubernetes fan? The state of PaaS in 2024
Not a Kubernetes fan? The state of PaaS in 2024Anthony Dahanne
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxRTS corp
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfkalichargn70th171
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...Bert Jan Schrijver
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorTier1 app
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingShane Coughlan
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...OnePlan Solutions
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxRTS corp
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 

Recently uploaded (20)

Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slides
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogue
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and Repair
 
2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh IT
 
Not a Kubernetes fan? The state of PaaS in 2024
Not a Kubernetes fan? The state of PaaS in 2024Not a Kubernetes fan? The state of PaaS in 2024
Not a Kubernetes fan? The state of PaaS in 2024
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryError
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 

RxJava for Android - GDG DevFest Ukraine 2015

  • 1. What it means to be Reactive? RxJava for Android Constantine Mars Senior Android Developer @ DataArt GDG Dnipro and JUG Dnepr
  • 2. –Ivan Morgillo, Alter Ego solutions, speech on DroidCon Berlin’2015 “A piece of cake, you know”
  • 3. #dfua Faces of the Reactive Programming World Ben Christensen, Netflix - RxJava Erik Meijer, Applied Duality - Rx.NET Jake Wharton, Square - RxAndroid Ivan Morgillo, Alter Ego - first book about RxAndroid
  • 6. #dfua The one who is listening is Observer And the other one, who is emitting events, is Subject, or Observable *Illustration from O’Reilly® HeadFirst “Design Patterns” book:
  • 7. #dfua This is well known interface in for both Android and Desktop developers Observer = Listener t.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Timber.d("something"); } }); .JAVA
  • 8. #dfua We will use it throughout presentation Lambda syntax t.setOnClickListener(v -> Timber.d("something")); .JAVA
  • 9. RxJava. Observable & Observer Basics
  • 10. #dfua It’s the source of events Observable rx.Observable<Integer> observable = rx.Observable.create( new rx.Observable.OnSubscribe<Integer>() { @Override public void call(Subscriber<? super Integer> subscriber) { for (int i = 0; i < N; i++) { Integer integer = random.nextInt(MAX); subscriber.onNext(integer); } subscriber.onCompleted(); } }); .JAVA Be aware: there is java.util.Observable besides rx.Observable - they’re not the same
  • 11. #dfua It’s the source of events. It handles subscriptions through OnSubscribe callback Observable rx.Observable<Integer> observable = rx.Observable.create( new rx.Observable.OnSubscribe<Integer>() { @Override public void call(Subscriber<? super Integer> subscriber) { for (int i = 0; i < N; i++) { Integer integer = random.nextInt(MAX); subscriber.onNext(integer); } subscriber.onCompleted(); } }); .JAVA Be aware: there is java.util.Observable besides rx.Observable - they’re not the same
  • 12. #dfua It’s the source of events. It handles subscriptions through OnSubscribe callback. When observer subscribes, it is named subscriber inside of a call() Observable rx.Observable<Integer> observable = rx.Observable.create( new rx.Observable.OnSubscribe<Integer>() { @Override public void call(Subscriber<? super Integer> subscriber) { for (int i = 0; i < N; i++) { Integer integer = random.nextInt(MAX); subscriber.onNext(integer); } subscriber.onCompleted(); } }); .JAVA Be aware: there is java.util.Observable besides rx.Observable - they’re not the same
  • 13. #dfua It’s the source of events. It handles subscriptions through OnSubscribe callback. When observer subscribes, it is named subscriber inside of a call() Observable rx.Observable<Integer> observable = rx.Observable.create( new rx.Observable.OnSubscribe<Integer>() { @Override public void call(Subscriber<? super Integer> subscriber) { for (int i = 0; i < N; i++) { Integer integer = random.nextInt(MAX); subscriber.onNext(integer); } subscriber.onCompleted(); } }); .JAVA Be aware: there is java.util.Observable besides rx.Observable - they’re not the same
  • 14. #dfua Observer rx.Observer<Integer> observer = new rx.Observer<Integer>() { @Override public void onCompleted() { display.show("completed"); } @Override public void onError(Throwable e) { display.show("error: " + e.getMessage()); } @Override public void onNext(Integer integer) { display.show("next: " + integer); } }; observable.subscribe(observer); .JAVA It’s the bunch of Reactive callbacks that should be registered through subscription.
  • 15. #dfua It’s the bunch of Reactive callbacks that should be registered through subscription. And handles incoming onNext(), onCompleted() and onError() from Observable Observer rx.Observer<Integer> observer = new rx.Observer<Integer>() { @Override public void onCompleted() { display.show("completed"); } @Override public void onError(Throwable e) { display.show("error: " + e.getMessage()); } @Override public void onNext(Integer integer) { display.show("next: " + integer); } }; observable.subscribe(observer); .JAVA
  • 16. #dfua But to make magic we need one more thing... Observer rx.Observer<Integer> observer = new rx.Observer<Integer>() { @Override public void onCompleted() { display.show("completed"); } @Override public void onError(Throwable e) { display.show("error: " + e.getMessage()); } @Override public void onNext(Integer integer) { display.show("next: " + integer); } }; observable.subscribe(observer); .JAVA
  • 17. #dfua To subscribe. This means creating Subscription. Subscription Subscription subscription = observable.subscribe(observer); ... if(!subscription.isUnsubscribed()) { subscription.unsubscribe(); } .JAVA
  • 18. #dfua To subscribe. This means creating Subscription. In fact Subscription class is rarely used, but can be useful to unsubscribe when we don’t need to receive events Subscription Subscription subscription = observable.subscribe(observer); ... if(!subscription.isUnsubscribed()) { subscription.unsubscribe(); } .JAVA
  • 19. #dfua Looks more readable, isn’t it? At least takes one screen, not three :) Observable + Observer with lambdas rx.Observable<Integer> observable = rx.Observable.create(subscriber -> { for (int i = 0; i < N; i++) subscriber.onNext(random.nextInt(MAX)); subscriber.onCompleted(); }); observable.subscribe( integer -> display.show("next: " + integer), throwable -> display.show("error: " + throwable.getMessage()), () -> display.show("completed")); .JAVA
  • 20. #dfua Reactive Systems are: *Check ReactiveManifesto.org for detailed definitions: Message Driven Responsive Resilient Scalable (Elastic)
  • 21. From everything, ...even from air :) Creating Observables
  • 22. #dfua Observable.from() ENTER FILENAME/LANG ArrayList<Integer> arrayList = new ArrayList<>(); int MAX_N = random.nextInt(12) + 5; for (int i = 0; i < MAX_N; i++) arrayList.add(random.nextInt(MAX)); rx.Observable.from(arrayList) .subscribe( integer -> display.show("next: " + integer), throwable -> display.show("error: " + throwable.getMessage()), () -> display.show("complete")); .JAVA
  • 23. #dfua Observable.just() ENTER FILENAME/LANG private List<Integer> generate() { Random r = new Random(); int n = r.nextInt(5) + 5; ArrayList<Integer> a = new ArrayList<>(); for (int i = 0; i < n; i++) a.add(r.nextInt(100)); return a; } public void just() { rx.Observable.just(generate()) .subscribe(integer -> display.show("next: " + integer), throwable -> display.show("error: " + throwable.getMessage()), () -> display.show("complete")); } .JAVA
  • 24. #dfua Observable.interval() Random r = new Random(); rx.Observable.interval(2, TimeUnit.SECONDS) .map(t -> new long[]{t, r.nextInt(100)}) .limit(5) .subscribe( tuple -> display.show("next: " + Arrays.toString(tuple)), throwable -> { }, () -> display.show("complete")); .JAVA
  • 25. #dfua Retrofit RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint("https://api.github.com") .build(); GitHubService service = restAdapter.create(GitHubService.class); // Retrofit can return observable which we handle as any other observable service.listRepos("c-mars") .flatMap(Observable::from) .limit(10) .subscribe(repo -> display.show("next: " + repo.toString()), throwable -> display.show("error: " + throwable.getMessage()), () -> display.show("completed")); .JAVA
  • 26. #dfua RxBindings Button button; ... RxView.clicks(button) .map(v -> ++counter) .debounce(500, TimeUnit.MILLISECONDS) .subscribe(c -> display.show("button " + c)); .JAVA
  • 28. #dfua Blocking private final AmmeterReadings[] data = { new AmmeterReadings(1, 0.5), ... }; private static float getMaxValue(AmmeterReadings[] data) { return MathObservable.max(rx.Observable.from(data) .map(AmmeterReadings::getCurrent)) .toBlocking().firstOrDefault(0L); } .JAVA By default rx.Observable is async. But it can be converted to BlockingObservable and return result in-place, using functional computations.
  • 29. #dfua first, last, take, orDefault private final AmmeterReadings[] data = { new AmmeterReadings(1, 0.5), ... }; private static float getMaxValue(AmmeterReadings[] data) { return MathObservable.max(rx.Observable.from(data) .map(AmmeterReadings::getCurrent)) .toBlocking().firstOrDefault(0L); } .JAVA We can take first, last or any item from BlockingObservable. If it’s empty, we can define default value.
  • 30. #dfua take from Observable private final AmmeterReadings[] data = { new AmmeterReadings(1, 0.5), ... }; private static float getMaxValue(AmmeterReadings[] data) { return MathObservable.max( rx.Observable.from(data) .map(AmmeterReadings::getCurrent) .takeLast(5) ) .toBlocking().firstOrDefault(0L); } .JAVA rx.Observable (non-blocking) provides method take() to take multiple items from stream.
  • 31. #dfua singleOrDefault rx.Observable.range(0, 0) .singleOrDefault(-1) .forEach(i -> getDisplay().show("single:" + i)); .JAVA Check whether rx.Observable contains only one event/item.
  • 32. #dfua defaultIfEmpty rx.Observable.range(0, max) .defaultIfEmpty(999) .forEach(i -> getDisplay().show("range 0->" + max + ", value (999 if empty):" + String.valueOf(i))); .JAVA Almost the same as singleOrDefault
  • 33. #dfua toIterable final Integer[] data = {200, 4, 145, -1, 10, -12, 80}; Iterable<Integer> iterable = rx.Observable.from(data) .toBlocking().toIterable(); for (Integer i : iterable) { display.show("iterable:" + i.toString()); } .JAVA BlockingObservable.toIterable() converts rx.Observable to collection
  • 34. #dfua forEach final Integer[] data = {200, 4, 145, -1, 10, -12, 80}; rx.Observable.from(data) .forEach(i -> display.show("iterable:" + i.toString())); .JAVA forEach() is just shorcut to .subscribe()
  • 35. #dfua takeUntil rx.Observable.range(0, 10) .takeUntil(i -> i == 5) .forEach(i -> getDisplay().show(String.valueOf(i))); // out: 0, 1, 2, 3, 4, 5 .JAVA Just a variant of take(), which completes when condition matches.
  • 36. #dfua contains rx.Observable.range(0, max) .contains(2) .forEach(i -> getDisplay().show("range: " + 0 + "->" + max + ",contains 2: " + String.valueOf(i))); // out: true (or false) .JAVA Check whether stream contains certain value
  • 37. #dfua filter rx.Observable.range(0, 10) .filter(i -> i > 5 && i < 9 ) .forEach(i -> getDisplay().show(i)); // out: 6, 7, 8 .JAVA Like takeUntil, just filter :)
  • 38. #dfua debounce long[] times = {3, 2, 1, 5, 2, 6}; rx.Observable<Pair<Integer, Long>> observable = rx.Observable.create(subscriber -> { int sz = times.length; for (int i = 0; i < sz; i++) { try { long t = times[i]; TimeUnit.MILLISECONDS.sleep(t); subscriber.onNext(new Pair<>(i, t)); } catch (InterruptedException e) { subscriber.onError(e); } } subscriber.onCompleted(); }); observable.debounce(4, TimeUnit.MILLISECONDS) .subscribe(pair -> getDisplay().show("out: value=" + pair.first + ", time=" + pair.second)); .JAVA
  • 39. #dfua sample long[] times = {3, 2, 1, 5, 4, 3, 1}; rx.Observable<Pair<Integer, Long>> observable = rx.Observable.create(subscriber -> { int sz = times.length; for (int i = 0; i < sz; i++) { try { long t = times[i]; TimeUnit.MILLISECONDS.sleep(t * 10); subscriber.onNext(new Pair<>(i, t)); } catch (InterruptedException e) { subscriber.onError(e); } } subscriber.onCompleted(); }); observable.sample(40, TimeUnit.MILLISECONDS) .subscribe(pair -> getDisplay().show("out: value=" + pair.first + "; time=" + pair.second)); .JAVA
  • 41. #dfua merge rx.Observable first = Observable.range(0, 5); //int[] rx.Observable second = Observable.from(new String[]{"one", "two", "three", "four", "five"}); //String[] rx.Observable.merge(first, second) .forEach(item -> getDisplay().show(item.toString())); .JAVA Merges items from separate rx.Observables to single stream
  • 42. #dfua zip rx.Observable<Integer> first = Observable.range(0, 5); //int[] rx.Observable<String> second = Observable.from(new String[]{"one", "two", "three", "four", "five"}); //String[] rx.Observable.zip(first, second, (i, s) -> new Pair(s, i)) .forEach(pair -> getDisplay().show(pair.toString())); .JAVA Merges items from separate rx.Observables to single stream using combining function.
  • 44. #dfua retry rx.Observable<Integer> canFail = rx.Observable.create(new Observable.OnSubscribe<Integer>() { @Override public void call(Subscriber<? super Integer> subscriber) { for (int i = 0; i < 6; i++) { switch (i) { case 3: if (!failedOnce) { failedOnce = true; subscriber.onError(new Error()); return; } break; case 5: subscriber.onError(new Throwable()); return; } subscriber.onNext(i); } subscriber.onCompleted(); } }); .JAVA
  • 45. #dfua retry canFail.retry((integer, throwable) -> { boolean retry = (throwable instanceof Error); getDisplay().show("retry, errors: " + integer); return retry; }) .subscribe(i -> { getDisplay().show(i); }, throwable -> { getDisplay().show("error: " + throwable.getMessage()); }); .JAVA
  • 46. #dfua retry In case of error we can check condition in retry() and then re-subscribe and try once more
  • 48. #dfua MathObservable private final AmmeterReadings[] data = { new AmmeterReadings(1, 0.5), ... }; private static float getMaxValue(AmmeterReadings[] data) { return MathObservable.max(rx.Observable.from(data) .map(AmmeterReadings::getCurrent)) .toBlocking().firstOrDefault(0L); } .JAVA Plugin MathObservable: compile 'io.reactivex:rxjava-math:1.0.0' max, average, sum, count
  • 49. #dfua Average rx.Observable<Integer> integers = rx.Observable.range(0, 10); MathObservable.averageInteger(integers).subscribe(avg -> { getDisplay().show(avg); }); .JAVA Many methods of MathObservable has type-aware alternatives
  • 50. #dfua reduce rx.Observable.range(0, 10).reduce((a, b) -> { int c = a + b; getDisplay().show("reduce: a=" + a + " + " + b + " = " + c); return c; }).forEach(value -> getDisplay().show("result: " + value)); .JAVA Classic reduce operation, common for all functional programming languages
  • 51. Ubiquitous mediums that like actors can play any role RxJava Subjects
  • 52. #dfua Creating Subjects PublishSubject<String> subject = PublishSubject.create(); example(subject); … ReplaySubject<String> subject = ReplaySubject.createWithSize(2); example(subject); .JAVA Subjects have method .create() for this. ReplaySubject can also be created with predefined number of events to replay on subscription.
  • 53. #dfua Example code private void example(Subject<String, String> subject) { subject.onNext("before 1"); subject.onNext("before 2"); subject.onNext("before 3"); subject.onNext("before 4"); subject.subscribe(s -> getDisplay().show("subscribed: " + s)); subject.onNext("after 5"); subject.onNext("after 6"); subject.onNext("after 7"); subject.onNext("after 8"); subject.onCompleted(); } .JAVA Subject can act both like Observable and Observer. So we can call .onNext, .onComplete manually and trigger subscription callbacks
  • 54. #dfua Subjects behaviour PublishSubject Is just a proxy for events AsyncSubject Replays only last event onComplete ReplaySubject Replays last N events and then proxies the same as Publish BehaviorSubject Replays only last event and then proxies the same as Publish
  • 55. #dfua ReactiveX Diagrams In a hour of despair - seek inspiration at ReactiveX.io
  • 57. #dfua Schedulers rx.Observable.from(readFromFile(context)) .subscribeOn(Schedulers.io()) .forEach(line -> textView.append("n" + line)); .JAVA By default rx.Observable is single-threaded. Here come Schedulers to hide threading and synchronization behind the functional interface. Just call .subscribeOn() and define which kind of threading you want
  • 58. #dfua Schedulers rx.Observable source = rx.Observable.range(0, 10).map(integer -> { List<Integer> outs = new ArrayList<>(); for (int i = 0; i < 1000; i++) { for (int j = 0; j < 1000; j++) { outs.add((int) Math.pow(i, j)); } } return outs; }).flatMap(Observable::from); MathObservable.sumInteger(source) .subscribeOn(Schedulers.computation()) .subscribe(integer -> textView.setText("final sum: " + integer.toString())); .JAVA
  • 59. #dfua Android UI MathObservable.sumInteger(source) .subscribeOn(Schedulers.computation()) .subscribe(integer -> textView.setText("final sum: " + integer.toString())); .JAVA Scheduler move execution to another appropriate thread. But when we try to update UI from this chain - something bad happens...
  • 60. #dfua Android UI MathObservable.sumInteger(source) .subscribeOn(Schedulers.computation()) .subscribe(integer -> textView.setText("final sum: " + integer.toString())); .JAVA Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. E/AndroidRuntime: at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6556) E/AndroidRuntime: at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:942) E/AndroidRuntime: at android.view.ViewGroup.invalidateChild(ViewGroup.java:5081) E/AndroidRuntime: at android.view.View.invalidateInternal(View.java:12713) E/AndroidRuntime: at android.view.View.invalidate(View.java:12677) E/AndroidRuntime: at android.view.View.invalidate(View.java:12661) ... CONSOLE
  • 63. #dfua AndroidSchedulers rx.Observable.from(readFromFile(context)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .forEach(line -> textView.append("n" + line)); .JAVA .subscribeOn defines thread on which computations run, .observeOn defines thread on which rx.Observer callbacks will run
  • 64. #dfua Activity Lifecycle // Activity private Subscription subscription; protected void onCreate(Bundle savedInstanceState) { this.subscription = observable.subscribe(this); } ... protected void onDestroy() { this.subscription.unsubscribe(); super.onDestroy(); } .JAVA Use subscription or CompositeSubscription
  • 66. #dfua Where to look? ● JavaDoc: http://reactivex.io/RxJava/javadoc/rx/Observable.html ● List of Additional Reading from RxJava Wiki: https://github.com/ReactiveX/RxJava/wiki/Additional-Reading ● RxJava Essentials by Ivan Morgillo: https://www.packtpub.com/application-development/rxjava-essentials ● RxMarbles - interactive diagrams: http://rxmarbles.com/