Share
Embed
Exploring RxJava 2 for Android (GOTOcph October 2016)
This talk will be an exploration on why reactive programming works so well for Android and how to use RxJava to apply it.
Video: https://www.youtube.com/watch?v=htIXKI5gOQU
Jake Wharton PRO
October 03, 2016
Transcript
207 slides
-
Why Reactive? Unless you can model your entire system synchronously,
a single asynchronous source breaks imperative programming. -
Why Reactive? interface UserManager { User getUser(); void setName(String name);
void setAge(int age); }A -
Why Reactive? interface UserManager { User getUser(); void setName(String name);
void setAge(int age); }A UserManager um = new UserManager(); -
Why Reactive? interface UserManager { User getUser(); void setName(String name);
void setAge(int age); }A UserManager um = new UserManager(); System.out.println(um.getUser()); -
Why Reactive? interface UserManager { User getUser(); void setName(String name);
void setAge(int age); }A UserManager um = new UserManager(); System.out.println(um.getUser()); um.setName("Jane Doe"); -
Why Reactive? interface UserManager { User getUser(); void setName(String name);
void setAge(int age); }A UserManager um = new UserManager(); System.out.println(um.getUser()); um.setName("Jane Doe"); System.out.println(um.getUser()); -
Why Reactive? interface UserManager { User getUser(); void setName(String name);
// <-- now async void setAge(int age); // <-- now async }A -
Why Reactive? interface UserManager { User getUser(); void setName(String name);
void setAge(int age); }A UserManager um = new UserManager(); System.out.println(um.getUser()); um.setName("Jane Doe"); System.out.println(um.getUser()); -
Why Reactive? interface UserManager { User getUser(); void setName(String name,
Runnable callback); void setAge(int age, Runnable callback); }A -
Why Reactive? interface UserManager { User getUser(); void setName(String name,
Runnable callback);A void setAge(int age, Runnable callback);B }A UserManager um = new UserManager(); System.out.println(um.getUser()); um.setName("Jane Doe", new Runnable() { @Override public void run() { System.out.println(um.getUser()); }X }); -
Why Reactive? interface UserManager { User getUser(); void setName(String name,
Listener listener);A void setAge(int age, Listener listener);B interface Listener { void success(User user); void failure(IOException e); }G }A -
Why Reactive? UserManager um = new UserManager(); System.out.println(um.getUser()); um.setName("Jane Doe",
new UserManager.Listener() { @Override public void success() { System.out.println(um.getUser()); }A @Override public void failure(IOException e) { // TODO show the error... }B }); -
Why Reactive? UserManager um = new UserManager(); System.out.println(um.getUser()); um.setName("Jane Doe",
new UserManager.Listener() { @Override public void success() { System.out.println(um.getUser()); }A @Override public void failure(IOException e) { // TODO show the error... }B }); um.setAge(40, new UserManager.Listener() { @Override public void success() { System.out.println(um.getUser()); }C 2@Override public void failure(IOException e) {2 2// TODO show the error...2 }D });2 -
Why Reactive? UserManager um = new UserManager(); System.out.println(um.getUser()); um.setName("Jane Doe",
new UserManager.Listener() { @Override public void success() { System.out.println(um.getUser()); um.setAge(40, new UserManager.Listener() { @Override public void success() { System.out.println(um.getUser()); }C 2@Override public void failure(IOException e) {2 2// TODO show the error...2 }D });2 }A @Override public void failure(IOException e) { // TODO show the error... }B }); -
Why Reactive? public final class UserActivity extends Activity { private
final UserManager um = new UserManager(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.user); TextView tv = (TextView) findViewById(R.id.user_name); tv.setText(um.getUser().toString()); um.setName("Jane Doe", new UserManager.Listener() { @Override public void success() { tv.setText(um.getUser().toString()); }A @Override public void failure(IOException e) { // TODO show the error... }B }); }Y }Z -
Why Reactive? public final class UserActivity extends Activity { private
final UserManager um = new UserManager(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.user); TextView tv = (TextView) findViewById(R.id.user_name); tv.setText(um.getUser().toString()); um.setName("Jane Doe", new UserManager.Listener() { @Override public void success() { tv.setText(um.getUser().toString()); }A @Override public void failure(IOException e) { // TODO show the error... }B }); }Y }Z -
Why Reactive? public final class UserActivity extends Activity { private
final UserManager um = new UserManager(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.user); TextView tv = (TextView) findViewById(R.id.user_name); tv.setText(um.getUser().toString()); um.setName("Jane Doe", new UserManager.Listener() { @Override public void success() { if (isDestroyed()) { tv.setText(um.getUser().toString()); } }A @Override public void failure(IOException e) { // TODO show the error... }B }); }Y }Z -
Why Reactive? public final class UserActivity extends Activity { private
final UserManager um = new UserManager(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.user); TextView tv = (TextView) findViewById(R.id.user_name); tv.setText(um.getUser().toString()); um.setName("Jane Doe", new UserManager.Listener() { @Override public void success() { if (isDestroyed()) { tv.setText(um.getUser().toString()); } }A @Override public void failure(IOException e) { // TODO show the error... }B }); }Y }Z -
Why Reactive? public final class UserActivity extends Activity { private
final UserManager um = new UserManager(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.user); TextView tv = (TextView) findViewById(R.id.user_name); tv.setText(um.getUser().toString()); um.setName("Jane Doe", new UserManager.Listener() { @Override public void success() { if (isDestroyed()) { tv.setText(um.getUser().toString()); }L }A @Override public void failure(IOException e) { // TODO show the error... }B }); }Y }Z -
Why Reactive? public final class UserActivity extends Activity { private
final UserManager um = new UserManager(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.user); TextView tv = (TextView) findViewById(R.id.user_name); tv.setText(um.getUser().toString()); um.setName("Jane Doe", new UserManager.Listener() { @Override public void success() { runOnUiThread(new Runnable() { @Override public void run() { if (isDestroyed()) { tv.setText(um.getUser().toString()); }L }4 }); }A @Override public void failure(IOException e) { // TODO show the error... }B }); }Y }Z -
Why Reactive? public final class UserActivity extends Activity { private
final UserManager um = new UserManager(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.user); TextView tv = (TextView) findViewById(R.id.user_name); tv.setText(um.getUser().toString()); um.setName("Jane Doe", new UserManager.Listener() { @Override public void success() { runOnUiThread(new Runnable() { @Override public void run() { if (isDestroyed()) { tv.setText(um.getUser().toString()); } }4 }); }A @Override public void failure(IOException e) { // TODO show the error... }B }); }Y }Z -
Why Reactive? GET / 200 OK SELECT * Jane Doe
setText onClick -
Why Reactive? GET / 200 OK SELECT * Jane Doe
setText onClick -
Why Reactive? GET / 200 OK SELECT * Jane Doe
setText onClick -
Why Reactive? GET / 200 OK SELECT * Jane Doe
setText onClick -
Why Reactive? GET / 200 OK SELECT * Jane Doe
setText onClick -
Why Reactive? Unless you can model your entire system synchronously,
a single asynchronous source breaks imperative programming. -
RxJava • A set of classes for representing sources of
data. • A set of classes for listening to data sources. -
RxJava • A set of classes for representing sources of
data. • A set of classes for listening to data sources. • A set of methods for modifying and composing the data. -
RxJava • A set of classes for representing sources of
data. • A set of classes for listening to data sources. • A set of methods for modifying and composing the data. -
Sources • Usually do work when you start or stop
listening. • Synchronous or asynchronous. -
Sources • Usually do work when you start or stop
listening. • Synchronous or asynchronous. • Single item or many items. -
Sources • Usually do work when you start or stop
listening. • Synchronous or asynchronous. • Single item, many items, or empty. -
Sources • Usually do work when you start or stop
listening. • Synchronous or asynchronous. • Single item, many items, or empty. • Terminates with an error or succeeds to completion. -
Sources • Usually do work when you start or stop
listening. • Synchronous or asynchronous. • Single item, many items, or empty. • Terminates with an error or succeeds to completion. • May never terminate! -
Sources • Usually do work when you start or stop
listening. • Synchronous or asynchronous. • Single item, many items, or empty. • Terminates with an error or succeeds to completion. • May never terminate! • Just an implementation of the Observer pattern. -
• Observable<T> • Emits 0 to n items. • Terminates
with complete or error. • Flowable<T> • Emits 0 to n items. • Terminates with complete or error. void void Sources -
• Observable<T> • Emits 0 to n items. • Terminates
with complete or error. • Does not have backpressure. • Flowable<T> • Emits 0 to n items. • Terminates with complete or error. • Has backpressure. void void Sources -
Flowable vs. Observable • Backpressure allows you to control how
fast a source emits items. -
Flowable vs. Observable • Backpressure allows you to control how
fast a source emits items. • RxJava 1.x added backpressure late in the design process. -
Flowable vs. Observable • Backpressure allows you to control how
fast a source emits items. • RxJava 1.x added backpressure late in the design process. • All types exposed backpressure but not all sources respected it. -
Flowable vs. Observable • Backpressure allows you to control how
fast a source emits items. • RxJava 1.x added backpressure late in the design process. • All types exposed backpressure but not all sources respected it. • Backpressure, like inheritance, must be designed for. -
Flowable vs. Observable • Backpressure, like inheritance, must be designed
for. Observable<MotionEvent> events = RxView.touches(paintView); -
Flowable vs. Observable • Backpressure, like inheritance, must be designed
for. Observable<MotionEvent> events = RxView.touches(paintView); Observable<Row> rows = db.createQuery("SELECT * …"); -
Flowable vs. Observable • Backpressure, like inheritance, must be designed
for. Observable<MotionEvent> events = RxView.touches(paintView); Observable<Row> rows = db.createQuery("SELECT * …"); -
Flowable vs. Observable • Backpressure, like inheritance, must be designed
for. Observable<MotionEvent> events = RxView.touches(paintView); Observable<Row> rows = db.createQuery("SELECT * …"); -
Flowable vs. Observable • Backpressure, like inheritance, must be designed
for. Observable<MotionEvent> events = RxView.touches(paintView); Observable<Row> rows = db.createQuery("SELECT * …"); -
Flowable vs. Observable • Backpressure, like inheritance, must be designed
for. Observable<MotionEvent> events = RxView.touches(paintView); Observable<Row> rows = db.createQuery("SELECT * …"); MissingBackpressureException -
Flowable vs. Observable • Backpressure, like inheritance, must be designed
for. Observable<MotionEvent> events = RxView.touches(paintView); Flowable<Row> rows = db.createQuery("SELECT * …"); -
Flowable vs. Observable Observable<MotionEvent> Flowable<Row> interface Subscriber<T> { void onNext(T
t); void onComplete(); void onError(Throwable t); void onSubscribe(Subscription s); }B interface Observer<T> { void onNext(T t); void onComplete(); void onError(Throwable t); void onSubscribe(Disposable d); }B -
Flowable vs. Observable Observable<MotionEvent> Flowable<Row> interface Subscriber<T> { void onNext(T
t); void onComplete(); void onError(Throwable t); void onSubscribe(Subscription s); }B interface Observer<T> { void onNext(T t); void onComplete(); void onError(Throwable t); void onSubscribe(Disposable d); }B -
Flowable vs. Observable Observable<MotionEvent> Flowable<Row> interface Subscriber<T> { void onNext(T
t); void onComplete(); void onError(Throwable t); void onSubscribe(Subscription s); }B interface Observer<T> { void onNext(T t); void onComplete(); void onError(Throwable t); void onSubscribe(Disposable d); }B -
Flowable vs. Observable Observable<MotionEvent> Flowable<Row> interface Subscriber<T> { void onNext(T
t); void onComplete(); void onError(Throwable t); void onSubscribe(Subscription s); }B interface Observer<T> { void onNext(T t); void onComplete(); void onError(Throwable t); void onSubscribe(Disposable d); }B -
Flowable vs. Observable Observable<MotionEvent> Flowable<Row> interface Subscriber<T> { void onNext(T
t); void onComplete(); void onError(Throwable t); void onSubscribe(Subscription s); }B interface Observer<T> { void onNext(T t); void onComplete(); void onError(Throwable t); void onSubscribe(Disposable d); }B -
Flowable vs. Observable Observable<MotionEvent> Flowable<Row> interface Subscriber<T> { void onNext(T
t); void onComplete(); void onError(Throwable t); void onSubscribe(Subscription s); }B interface Observer<T> { void onNext(T t); void onComplete(); void onError(Throwable t); void onSubscribe(Disposable d); }B interface Disposable { void dispose(); }B -
Flowable vs. Observable Observable<MotionEvent> Flowable<Row> interface Subscriber<T> { void onNext(T
t); void onComplete(); void onError(Throwable t); void onSubscribe(Subscription s); }B interface Observer<T> { void onNext(T t); void onComplete(); void onError(Throwable t); void onSubscribe(Disposable d); }B interface Disposable { void dispose(); }B interface Subscription { void cancel(); void request(long r); }B -
Reactive Streams ...is an initiative to provide a standard for
asynchronous stream processing with non-blocking back pressure. -
Reactive Streams interface Publisher<T> { void subscribe(Subscriber<? super T> s);
}A interface Subscriber<T> { void onNext(T t); void onComplete(); void onError(Throwable t); void onSubscribe(Subscription s); }B -
Reactive Streams interface Publisher<T> { void subscribe(Subscriber<? super T> s);
}A interface Subscriber<T> { void onNext(T t); void onComplete(); void onError(Throwable t); void onSubscribe(Subscription s); }B interface Subscription { void request(long n); void cancel(); }C -
Reactive Streams interface Publisher<T> { void subscribe(Subscriber<? super T> s);
}A interface Subscriber<T> { void onNext(T t); void onComplete(); void onError(Throwable t); void onSubscribe(Subscription s); }B interface Subscription { void request(long n); void cancel(); }C interface Processor<T, R> extends Subscriber<T>, Publisher<R> { }D -
Single • Either succeeds with an item or errors. •
No backpressure support. -
Single • Either succeeds with an item or errors. •
No backpressure support. • Think "reactive scalar". -
Completable • Either completes or errors. Has no items! •
No backpressure support. -
Completable • Either completes or errors. Has no items! •
No backpressure support. • Think "reactive runnable". -
Maybe • Either succeeds with an item, completes with no
items, or errors. • No backpressure support. -
Maybe • Either succeeds with an item, completes with no
items, or errors. • No backpressure support. • Think "reactive optional". -
Source Specializations • Encoding subsets of Observable into the type
system. • Single – Item or error. Think "scalar". • Completable – Complete or error. Think "runnable". • Maybe – Item, complete, or error. Think "optional". -
Reactive Streams (Backpressure) No Backpressure 0…n items, complete|error Flowable Observable
item|complete|error Maybe item|error Single complete|error Completable -
Sources interface UserManager { Observable<User> getUser(); Completable setName(String name); Completable
setAge(int age); }A void void -
Creating Sources String[] array = { "Hello", "World" }; List<String>
list = Arrays.asList(array); Flowable.fromArray(array); Flowable.fromIterable(list); Observable.fromArray(array); Observable.fromIterable(list); -
Creating Sources Observable.fromCallable(new Callable<String>() { @Override public String call() {Y
return getName(); }X }); -
Creating Sources Observable.fromCallable(new Callable<String>() { @Override public String call() throws
Exception {Y return getName();Z }X }); -
Creating Sources OkHttpClient client = // … Request request =
// … Observable.fromCallable(new Callable<String>() { @Override public String call() throws Exception {Y return client.newCall(request).execute();Z }X }); getName() -
Creating Sources Flowable.fromCallable(() -> "Hello"); Observable.fromCallable(() -> "Hello");
Maybe.fromCallable(() -> "Hello"); Single.fromCallable(() -> "Hello"); Completable.fromCallable(() -> "Ignored!"); -
Creating Sources Flowable.fromCallable(() -> "Hello"); Observable.fromCallable(() -> "Hello");
Maybe.fromCallable(() -> "Hello"); Maybe.fromAction(() -> System.out.println("Hello")); Maybe.fromRunnable(() -> System.out.println("Hello")) Single.fromCallable(() -> "Hello"); Completable.fromCallable(() -> "Ignored!"); Completable.fromAction(() -> System.out.println("Hello")); Completable.fromRunnable(() -> System.out.println("Hello")); -
Creating Sources Observable.create(new ObservableOnSubscribe<String>() { @Override public void subscribe(ObservableEmitter<String> e)
throws Exception { e.onNext("Hello"); e.onComplete(); }X }); -
Creating Sources Observable.create(new ObservableOnSubscribe<String>() { @Override public void subscribe(ObservableEmitter<String> e)
throws Exception { e.onNext("Hello"); e.onComplete(); }X }); -
Creating Sources Observable.create(new ObservableOnSubscribe<String>() { @Override public void subscribe(ObservableEmitter<String> e)
throws Exception { e.onNext("Hello"); e.onComplete(); }X }); -
Creating Sources Observable.create(new ObservableOnSubscribe<String>() { @Override public void subscribe(ObservableEmitter<String> e)
throws Exception { e.onNext("Hello"); e.onComplete(); }X }); -
Creating Sources OkHttpClient client = // … Request request =
// … Observable.create(e -> { client.newCall(request).enqueue(new Callback() { @Override public void onResponse(Response r) throws IOException { e.onNext(r.body().string()); e.onComplete(); }A @Override public void onFailure(IOException e) { e.onError(e); }B }); }); -
Creating Sources OkHttpClient client = // … Request request =
// … Observable.create(e -> { Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onResponse(Response r) throws IOException { e.onNext(r.body().string()); e.onComplete(); }A @Override public void onFailure(IOException e) { e.onError(e); }B }); }); -
Creating Sources OkHttpClient client = // … Request request =
// … Observable.create(e -> { Call call = client.newCall(request); e.setCancelation(() -> call.cancel()); call.enqueue(new Callback() { @Override public void onResponse(Response r) throws IOException { e.onNext(r.body().string()); e.onComplete(); }A @Override public void onFailure(IOException e) { e.onError(e); }B }); }); -
Creating Sources OkHttpClient client = // … Request request =
// … Observable.create(e -> { Call call = client.newCall(request); e.setCancelation(() -> call.cancel()); call.enqueue(new Callback() { @Override public void onResponse(Response r) throws IOException { e.onNext(r.body().string()); e.onComplete(); }A @Override public void onFailure(IOException e) { e.onError(e); }B }); }); -
Creating Sources View view = // … Observable.create(e -> {
e.setCancelation(() -> view.setOnClickListener(null)); view.setOnClickListener(v -> e.onNext(v)); }); -
Creating Sources Flowable.create(e -> { … }); Observable.create(e -> {
… }); Maybe.create(e -> { … }); Single.create(e -> { … }); Completable.create(e -> { … }); -
Observing Sources Observable<String> Flowable<String> interface Subscriber<T> { void onNext(T t);
void onComplete(); void onError(Throwable t); void onSubscribe(Subscription s); }B interface Observer<T> { void onNext(T t); void onComplete(); void onError(Throwable t); void onSubscribe(Disposable d); }B -
Observing Sources Observable<String> Flowable<String> interface Subscriber<T> { void onNext(T t);
void onComplete(); void onError(Throwable t); void onSubscribe(Subscription s); }B interface Observer<T> { void onNext(T t);A void onComplete();B void onError(Throwable t);C void onSubscribe(Disposable d);D }B interface Disposable { void dispose(); }B interface Subscription { void cancel(); void request(long r); }B -
Observing Sources Observable<String> o = Observable.just("Hello"); o.subscribe(new Observer<String>() { @Override
public void onNext(String s) { … } @Override public void onComplete() { … } @Override public void onError(Throwable t) { … } @Override public void onSubscribe(Disposable d) { ??? }B }); Flowable<String> interface Subscriber<T> { void onNext(T t); void onComplete(); void onError(Throwable t); void onSubscribe(Subscription s); }B interface Disposable { void dispose(); }B interface Subscription { void cancel(); void request(long r); }B interface T T t ;A ;B ;C ;D -
Observing Sources Observable<String> o = Observable.just("Hello"); o.subscribe(new DisposableObserver<String>() { @Override
public void onNext(String s) { … } @Override public void onComplete() { … } @Override public void onError(Throwable t) { … } }); @Override public void onSubscribe(Disposable d) { ??? }B -
Observing Sources Observable<String> o = Observable.just("Hello"); o.subscribe(new DisposableObserver<String>() { @Override
public void onNext(String s) { … } @Override public void onComplete() { … } @Override public void onError(Throwable t) { … } });Z // TODO how do we dispose??? -
Observing Sources Observable<String> o = Observable.just("Hello"); DisposableObserver observer = new
DisposableObserver<String>() { @Override public void onNext(String s) { … } @Override public void onComplete() { … } @Override public void onError(Throwable t) { … } } o.subscribe(observer);Z // TODO how do we dispose?????? -
Observing Sources Observable<String> o = Observable.just("Hello"); DisposableObserver observer = new
DisposableObserver<String>() { @Override public void onNext(String s) { … } @Override public void onComplete() { … } @Override public void onError(Throwable t) { … } } o.subscribe(observer);Z observer.dispose(); -
Observing Sources Observable<String> o = Observable.just("Hello"); o.subscribe(new DisposableObserver<String>() { @Override
public void onNext(String s) { … } @Override public void onComplete() { … } @Override public void onError(Throwable t) { … } });Z -
Observing Sources Observable<String> o = Observable.just("Hello"); o.subscribeWith(new DisposableObserver<String>() { @Override
public void onNext(String s) { … } @Override public void onComplete() { … } @Override public void onError(Throwable t) { … } });Z -
Observing Sources Observable<String> o = Observable.just("Hello"); Disposable d = o.subscribeWith(new
DisposableObserver<String>() { @Override public void onNext(String s) { … } @Override public void onComplete() { … } @Override public void onError(Throwable t) { … } });Z d.dispose(); -
Observing Sources Observable<String> o = Observable.just("Hello"); CompositeDisposable disposables = new
CompositeDisposable(); disposables.add(o.subscribeWith(new DisposableObserver<String>() { @Override public void onNext(String s) { … } @Override public void onComplete() { … } @Override public void onError(Throwable t) { … } }));Z disposables.dispose(); d.dispose(); Disposable d = -
Observing Sources Observable<String> o = Observable.just("Hello"); o.subscribeWith(new DisposableObserver<String>() { …
});Z Maybe<String> m = Maybe.just("Hello"); m.subscribeWith(new DisposableMaybeObserver<String>() { … });Z Single<String> s = Single.just("Hello"); s.subscribeWith(new DisposableSingleObserver<String>() { … });Z Completable c = Completable.completed(); c.subscribeWith(new DisposableCompletableObserver<String>() { … });Z disposables.add( @Override public void onNext(String s) { … } @Override public void onComplete() { … } @Override public void onError(Throwable t) { … } ) disposables.dispose(); -
Observing Sources Flowable<String> f = Flowable.just("Hello"); f.subscribeWith(new DisposableSubscriber<String>() { …
}); Observable<String> o = Observable.just("Hello"); o.subscribeWith(new DisposableObserver<String>() { … }); Maybe<String> m = Maybe.just("Hello"); m.subscribeWith(new DisposableMaybeObserver<String>() { … }); Single<String> s = Single.just("Hello"); s.subscribeWith(new DisposableSingleObserver<String>() { … }); Completable c = Completable.completed(); c.subscribeWith(new DisposableCompletableObserver<String>() { … }); -
Observing Sources Flowable<String> f = Flowable.just("Hello"); f.subscribeWith(new DisposableSubscriber<String>() { …
}); Observable<String> o = Observable.just("Hello"); o.subscribeWith(new DisposableObserver<String>() { … }); Maybe<String> m = Maybe.just("Hello"); m.subscribeWith(new DisposableMaybeObserver<String>() { … }); Single<String> s = Single.just("Hello"); s.subscribeWith(new DisposableSingleObserver<String>() { … }); Completable c = Completable.completed(); c.subscribeWith(new DisposableCompletableObserver<String>() { … }); -
Observing Sources Flowable<String> f = Flowable.just("Hello"); Disposable d1 = f.subscribeWith(new
DisposableSubscriber<String>() { … }); Observable<String> o = Observable.just("Hello"); Disposable d2 = o.subscribeWith(new DisposableObserver<String>() { … }); Maybe<String> m = Maybe.just("Hello"); Disposable d3 = m.subscribeWith(new DisposableMaybeObserver<String>() { … }); Single<String> s = Single.just("Hello"); Disposable d4 = s.subscribeWith(new DisposableSingleObserver<String>() { … }); Completable c = Completable.completed(); Disposable d5 = c.subscribeWith(new DisposableCompletableObserver<String>() { … }); -
RxJava • A set of classes for representing sources of
data. • A set of classes for listening to data sources. • A set of methods for modifying and composing data. -
RxJava • A set of classes for representing sources of
data. • A set of classes for listening to data sources. • A set of methods for modifying and composing data. -
Operators • Manipulate or combine data in some way. •
Manipulate threading in some way. -
Operators • Manipulate or combine data in some way. •
Manipulate threading in some way. • Manipulate emissions in some way. -
Operators @Override public void success() { runOnUiThread(new Runnable() { @Override
public void run() { tv.setText(um.getUser().toString()); }4 }); }A -
Operators OkHttpClient client = // … Request request = //
… Response response = client.newCall(request).execute(); -
Operators OkHttpClient client = // … Request request = //
… Observable<Response> response = Observable.fromCallable(() -> { return client.newCall(request).execute(); }); -
Operators OkHttpClient client = // … Request request = //
… Observable<Response> response = Observable.fromCallable(() -> { return client.newCall(request).execute(); }); Observable<Response> backgroundResponse = response.subscribeOn(Schedulers.io()); -
Operators OkHttpClient client = // … Request request = //
… Observable<Response> response = Observable.fromCallable(() -> { return client.newCall(request).execute(); }); Observable<Response> backgroundResponse = response.subscribeOn(Schedulers.io()); -
Operators OkHttpClient client = // … Request request = //
… Observable<Response> response = Observable.fromCallable(() -> { return client.newCall(request).execute(); }); Observable<Response> backgroundResponse = response.subscribeOn(Schedulers.io()); -
Operators OkHttpClient client = // … Request request = //
… Observable<Response> response = Observable.fromCallable(() -> { return client.newCall(request).execute(); }) .subscribeOn(Schedulers.io());Y -
Operators OkHttpClient client = // … Request request = //
… Observable<Response> response = Observable.fromCallable(() -> { return client.newCall(request).execute(); }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread());Y -
Operators OkHttpClient client = // … Request request = //
… Observable<Response> response = Observable.fromCallable(() -> { return client.newCall(request).execute(); }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .map(response -> response.body().string());Y -
Operators OkHttpClient client = // … Request request = //
… Observable<Response> response = Observable.fromCallable(() -> { return client.newCall(request).execute(); }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .map(response -> response.body().string());Y// NetworkOnMainThread! -
Operators OkHttpClient client = // … Request request = //
… Observable<Response> response = Observable.fromCallable(() -> { return client.newCall(request).execute(); }) .subscribeOn(Schedulers.io()) .map(response -> response.body().string()) // Ok! .observeOn(AndroidSchedulers.mainThread());Y// NetworkOnMainThread! -
Operator Specialization 1 2 3 4 5 6 7 8
9 10 11 first() 1 Observable Observable -
Operator Specialization 1 2 3 4 5 6 7 8
9 10 11 get(0) 1 List<Long> List<Long> -
Operator Specialization 1 2 3 4 5 6 7 8
9 10 11 first() 1 Observable Single -
Operator Specialization 1 2 3 4 5 6 7 8
9 ignoreElements() Observable Completable -
Flowable Observable Maybe Single Completable Flowable toObservable() reduce() elementAt() firstElement()
lastElement() singleElement() scan() elementAt() first()/firstOrError() last()/lastOrError() single/singleOrError() all()/any()/count() (and more) ignoreElements() Observable toFlowable() reduce() elementAt() firstElement() lastElement() singleElement() scan() elementAt() first()/firstOrError() last()/lastOrError() single/singleOrError() all()/any()/count() (and more) ignoreElements() Maybe toFlowable() toObservable() toSingle() sequenceEqual() toCompletable() Single toFlowable() toObservable() toMaybe() toCompletable() Completable toFlowable() toObservable() toMaybe() toSingle() toSingleDefault() From To -
Flowable Observable Maybe Single Completable Flowable toObservable() reduce() elementAt() firstElement()
lastElement() singleElement() scan() elementAt() first()/firstOrError() last()/lastOrError() single/singleOrError() all()/any()/count() (and more) ignoreElements() Observable toFlowable() reduce() elementAt() firstElement() lastElement() singleElement() scan() elementAt() first()/firstOrError() last()/lastOrError() single/singleOrError() all()/any()/count() (and more) ignoreElements() Maybe toFlowable() toObservable() toSingle() sequenceEqual() toCompletable() Single toFlowable() toObservable() toMaybe() toCompletable() Completable toFlowable() toObservable() toMaybe() toSingle() toSingleDefault() From To -
Flowable Observable Maybe Single Completable Flowable toObservable() reduce() elementAt() firstElement()
lastElement() singleElement() scan() elementAt() first()/firstOrError() last()/lastOrError() single/singleOrError() all()/any()/count() (and more) ignoreElements() Observable toFlowable() reduce() elementAt() firstElement() lastElement() singleElement() scan() elementAt() first()/firstOrError() last()/lastOrError() single/singleOrError() all()/any()/count() (and more) ignoreElements() Maybe toFlowable() toObservable() toSingle() sequenceEqual() toCompletable() Single toFlowable() toObservable() toMaybe() toCompletable() Completable toFlowable() toObservable() toMaybe() toSingle() toSingleDefault() From To -
Being Reactive um.getUser() .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableObserver<User>() { @Override public void
onNext(User user) { }1 @Override public void onComplete() { /* ignored */ } @Override public void onError(Throwable t) { /* crash or show */ } }); -
Being Reactive um.getUser() .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableObserver<User>() { @Override public void
onNext(User user) { tv.setText(user.toString()); }1 @Override public void onComplete() { /* ignored */ } @Override public void onError(Throwable t) { /* crash or show */ } });2 -
Being Reactive disposables.add(um.getUser() .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableObserver<User>() { @Override public void
onNext(User user) { tv.setText(user.toString()); }1 @Override public void onComplete() { /* ignored */ } @Override public void onError(Throwable t) { /* crash or show */ } }));2 -
Being Reactive // onCreate disposables.add(um.getUser() .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableObserver<User>() { @Override
public void onNext(User user) { tv.setText(user.toString()); }1 @Override public void onComplete() { /* ignored */ } @Override public void onError(Throwable t) { /* crash or show */ } })); // onDestroy disposables.dispose(); -
Being Reactive um.setName("Jane Doe") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableCompletableObserver() { @Override
public void onComplete() { }1 @Override public void onError(Throwable t) { // retry or show }2 }); -
Being Reactive um.setName("Jane Doe") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableCompletableObserver() { @Override
public void onComplete() { // success! re-enable editing }1 @Override public void onError(Throwable t) { // retry or show }2 });3 -
Being Reactive disposables.add(um.setName("Jane Doe") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableCompletableObserver() { @Override
public void onComplete() { // success! re-enable editing }1 @Override public void onError(Throwable t) { // retry or show }2 }));3 -
Architecture • Less allocation to create a stream. • Less
overhead when subscribing to a stream. -
RxJava 2 • Build an app that reacts properly instead
of copes desperately! -
RxJava 2 • Build an app that reacts properly instead
of copes desperately! • Final release scheduled for 2016-10-29. -
Living with 1.x and 2.x class RxJavaInterop { static <T>
Flowable<T> toV2Flowable(rx.Observable<T> o) { … } static <T> Observable<T> toV2Observable(rx.Observable<T> o) { … } static <T> Maybe<T> toV2Maybe(rx.Single<T> s) { … } static <T> Maybe<T> toV2Maybe(rx.Completable c) { … } static <T> Single<T> toV2Single(rx.Single<T> s) { … } static Completable toV2Completable(rx.Completable c) { … } static <T> rx.Observable<T> toV1Observable(Publisher<T> p) { … } static <T> rx.Observable<T> toV1Observable(Observable<T> o, …) { … } static <T> rx.Single<T> toV1Single(Single<T> o) { … } static <T> rx.Single<T> toV1Single(Maybe<T> m) { … } static rx.Completable toV1Completable(Completable c) { … } static rx.Completable toV1Completable(Maybe<T> m) { … } }X -
Living with 1.x and 2.x class RxJavaInterop { static <T>
Flowable<T> toV2Flowable(rx.Observable<T> o) { … } static <T> Observable<T> toV2Observable(rx.Observable<T> o) { … } static <T> Maybe<T> toV2Maybe(rx.Single<T> s) { … } static <T> Maybe<T> toV2Maybe(rx.Completable c) { … } static <T> Single<T> toV2Single(rx.Single<T> s) { … } static Completable toV2Completable(rx.Completable c) { … } static <T> rx.Observable<T> toV1Observable(Publisher<T> p) { … } static <T> rx.Observable<T> toV1Observable(Observable<T> o, …) { … } static <T> rx.Single<T> toV1Single(Single<T> o) { … } github.com/akarnokd/RxJava2Interop