Slide 1

Slide 1 text

Exploring RxJava Jake Wharton

Slide 2

Slide 2 text

Exploring RxJava 2 Jake Wharton

Slide 3

Slide 3 text

Why Reactive? Unless you can model your entire system synchronously...

Slide 4

Slide 4 text

Why Reactive? Unless you can model your entire system synchronously, a single asynchronous source breaks imperative programming.

Slide 5

Slide 5 text

Why Reactive? interface UserManager { User getUser();
 }A

Slide 6

Slide 6 text

Why Reactive? interface UserManager { User getUser(); void setName(String name); void setAge(int age);
 }A

Slide 7

Slide 7 text

Why Reactive? interface UserManager { User getUser(); void setName(String name); void setAge(int age);
 }A UserManager um = new UserManager();

Slide 8

Slide 8 text

Why Reactive? interface UserManager { User getUser(); void setName(String name); void setAge(int age);
 }A UserManager um = new UserManager(); System.out.println(um.getUser());

Slide 9

Slide 9 text

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");

Slide 10

Slide 10 text

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());

Slide 11

Slide 11 text

Why Reactive? interface UserManager { User getUser(); void setName(String name); // <-- now async void setAge(int age); // <-- now async
 }A

Slide 12

Slide 12 text

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());

Slide 13

Slide 13 text

Why Reactive? interface UserManager { User getUser(); void setName(String name, Runnable callback); void setAge(int age, Runnable callback);
 }A

Slide 14

Slide 14 text

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 });

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

Why Reactive? UserManager um = new UserManager(); System.out.println(um.getUser()); um.setName("Jane Doe");

Slide 17

Slide 17 text

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 });

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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 });

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

Why Reactive? GET / 200 OK SELECT * Jane Doe setText onClick

Slide 28

Slide 28 text

Why Reactive? GET / 200 OK SELECT * Jane Doe setText onClick

Slide 29

Slide 29 text

Why Reactive? GET / 200 OK SELECT * Jane Doe setText onClick

Slide 30

Slide 30 text

Why Reactive? GET / 200 OK SELECT * Jane Doe setText onClick

Slide 31

Slide 31 text

Why Reactive? GET / 200 OK SELECT * Jane Doe setText onClick

Slide 32

Slide 32 text

Why Reactive?

Slide 33

Slide 33 text

Why Reactive?

Slide 34

Slide 34 text

Why Reactive? Unless you can model your entire system synchronously, a single asynchronous source breaks imperative programming.

Slide 35

Slide 35 text

Why Reactive?

Slide 36

Slide 36 text

Why Reactive?

Slide 37

Slide 37 text

Why Reactive?

Slide 38

Slide 38 text

Why Reactive?

Slide 39

Slide 39 text

Why Reactive?

Slide 40

Slide 40 text

Why Reactive?

Slide 41

Slide 41 text

RxJava

Slide 42

Slide 42 text

RxJava • A set of classes for representing sources of data.

Slide 43

Slide 43 text

RxJava • A set of classes for representing sources of data. • A set of classes for listening to data sources.

Slide 44

Slide 44 text

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.

Slide 45

Slide 45 text

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.

Slide 46

Slide 46 text

Sources

Slide 47

Slide 47 text

Sources • Usually do work when you start or stop listening.

Slide 48

Slide 48 text

Sources • Usually do work when you start or stop listening. • Synchronous or asynchronous.

Slide 49

Slide 49 text

Sources • Usually do work when you start or stop listening. • Synchronous or asynchronous. • Single item or many items.

Slide 50

Slide 50 text

Sources • Usually do work when you start or stop listening. • Synchronous or asynchronous. • Single item, many items, or empty.

Slide 51

Slide 51 text

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.

Slide 52

Slide 52 text

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!

Slide 53

Slide 53 text

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.

Slide 54

Slide 54 text

• Observable • Flowable void void
 Sources

Slide 55

Slide 55 text

• Observable • Emits 0 to n items. • Terminates with complete or error. • Flowable • Emits 0 to n items. • Terminates with complete or error. void void
 Sources

Slide 56

Slide 56 text

• Observable • Emits 0 to n items. • Terminates with complete or error. • Does not have backpressure. • Flowable • Emits 0 to n items. • Terminates with complete or error. • Has backpressure. void void
 Sources

Slide 57

Slide 57 text

Flowable vs. Observable

Slide 58

Slide 58 text

Flowable vs. Observable • Backpressure allows you to control how fast a source emits items.

Slide 59

Slide 59 text

Flowable vs. Observable • Backpressure allows you to control how fast a source emits items. • RxJava 1.x added backpressure late in the design process.

Slide 60

Slide 60 text

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.

Slide 61

Slide 61 text

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.

Slide 62

Slide 62 text

Flowable vs. Observable • Backpressure, like inheritance, must be designed for.

Slide 63

Slide 63 text

Flowable vs. Observable • Backpressure, like inheritance, must be designed for. Observable events = RxView.touches(paintView);

Slide 64

Slide 64 text

Flowable vs. Observable • Backpressure, like inheritance, must be designed for. Observable events = RxView.touches(paintView); Observable rows = db.createQuery("SELECT * …");

Slide 65

Slide 65 text

Flowable vs. Observable • Backpressure, like inheritance, must be designed for. Observable events = RxView.touches(paintView); Observable rows = db.createQuery("SELECT * …");

Slide 66

Slide 66 text

Flowable vs. Observable • Backpressure, like inheritance, must be designed for. Observable events = RxView.touches(paintView); Observable rows = db.createQuery("SELECT * …");

Slide 67

Slide 67 text

Flowable vs. Observable • Backpressure, like inheritance, must be designed for. Observable events = RxView.touches(paintView); Observable rows = db.createQuery("SELECT * …");

Slide 68

Slide 68 text

Flowable vs. Observable • Backpressure, like inheritance, must be designed for. Observable events = RxView.touches(paintView); Observable rows = db.createQuery("SELECT * …"); MissingBackpressureException

Slide 69

Slide 69 text

Flowable vs. Observable • Backpressure, like inheritance, must be designed for. Observable events = RxView.touches(paintView); Flowable rows = db.createQuery("SELECT * …");

Slide 70

Slide 70 text

Flowable vs. Observable Observable Flowable

Slide 71

Slide 71 text

Flowable vs. Observable Observable Flowable interface Subscriber {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Subscription s);
 }B interface Observer {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Disposable d);
 }B

Slide 72

Slide 72 text

Flowable vs. Observable Observable Flowable interface Subscriber {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Subscription s);
 }B interface Observer {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Disposable d);
 }B

Slide 73

Slide 73 text

Flowable vs. Observable Observable Flowable interface Subscriber {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Subscription s);
 }B interface Observer {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Disposable d);
 }B

Slide 74

Slide 74 text

Flowable vs. Observable Observable Flowable interface Subscriber {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Subscription s);
 }B interface Observer {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Disposable d);
 }B

Slide 75

Slide 75 text

Flowable vs. Observable Observable Flowable interface Subscriber {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Subscription s);
 }B interface Observer {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Disposable d);
 }B

Slide 76

Slide 76 text

Flowable vs. Observable Observable Flowable interface Subscriber {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Subscription s);
 }B interface Observer {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Disposable d);
 }B interface Disposable {
 void dispose();
 }B

Slide 77

Slide 77 text

Flowable vs. Observable Observable Flowable interface Subscriber {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Subscription s);
 }B interface Observer {
 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

Slide 78

Slide 78 text

Backpressure No Backpressure 0…n items, complete|error Flowable Observable

Slide 79

Slide 79 text

Reactive Streams ...is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure.

Slide 80

Slide 80 text

Reactive Streams interface Publisher {
 void subscribe(Subscriber super T> s);
 }A

Slide 81

Slide 81 text

Reactive Streams interface Publisher {
 void subscribe(Subscriber super T> s);
 }A interface Subscriber {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Subscription s);
 }B

Slide 82

Slide 82 text

Reactive Streams interface Publisher {
 void subscribe(Subscriber super T> s);
 }A interface Subscriber {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Subscription s);
 }B interface Subscription {
 void request(long n);
 void cancel();
 }C

Slide 83

Slide 83 text

Reactive Streams interface Publisher {
 void subscribe(Subscriber super T> s);
 }A interface Subscriber {
 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 extends Subscriber, Publisher {
 }D


Slide 84

Slide 84 text

Backpressure No Backpressure 0…n items, complete|error Flowable Observable

Slide 85

Slide 85 text

Reactive Streams (Backpressure) No Backpressure 0…n items, complete|error Flowable Observable

Slide 86

Slide 86 text

interface UserManager { User getUser(); void setName(String name); void setAge(int age);
 }A Sources

Slide 87

Slide 87 text

Sources interface UserManager { Observable getUser(); void setName(String name); void setAge(int age);
 }A

Slide 88

Slide 88 text

Source Specializations

Slide 89

Slide 89 text

Source Specializations • Encoding subsets of Observable into the type system.

Slide 90

Slide 90 text

Single • Either succeeds with an item or errors. • No backpressure support.

Slide 91

Slide 91 text

Single • Either succeeds with an item or errors. • No backpressure support. • Think "reactive scalar".

Slide 92

Slide 92 text

Completable • Either completes or errors. Has no items! • No backpressure support.

Slide 93

Slide 93 text

Completable • Either completes or errors. Has no items! • No backpressure support. • Think "reactive runnable".

Slide 94

Slide 94 text

Maybe • Either succeeds with an item, completes with no items, or errors. • No backpressure support.

Slide 95

Slide 95 text

Maybe • Either succeeds with an item, completes with no items, or errors. • No backpressure support. • Think "reactive optional".

Slide 96

Slide 96 text

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".

Slide 97

Slide 97 text

Reactive Streams (Backpressure) No Backpressure 0…n items, complete|error Flowable Observable item|complete|error Maybe item|error Single complete|error Completable

Slide 98

Slide 98 text

Sources interface UserManager { Observable getUser(); void setName(String name); void setAge(int age);
 }A

Slide 99

Slide 99 text

Sources interface UserManager { Observable getUser(); Completable setName(String name); Completable setAge(int age);
 }A void void


Slide 100

Slide 100 text

Creating Sources

Slide 101

Slide 101 text

Creating Sources Flowable.just("Hello");
 Flowable.just("Hello", "World"); 
 Observable.just("Hello");
 Observable.just("Hello", "World");
 Maybe.just("Hello");
 Single.just("Hello");

Slide 102

Slide 102 text

Creating Sources String[] array = { "Hello", "World" };
 List list = Arrays.asList(array);
 Flowable.fromArray(array); Flowable.fromIterable(list); Observable.fromArray(array); Observable.fromIterable(list);

Slide 103

Slide 103 text

Creating Sources Observable.fromCallable(new Callable() {
 @Override public String call() {Y
 return getName();
 }X
 });

Slide 104

Slide 104 text

Creating Sources Observable.fromCallable(new Callable() {
 @Override public String call() throws Exception {Y
 return getName();Z
 }X
 });

Slide 105

Slide 105 text

Creating Sources OkHttpClient client = // … Request request = // … Observable.fromCallable(new Callable() {
 @Override public String call() throws Exception {Y
 return client.newCall(request).execute();Z
 }X
 }); 
 
 getName()

Slide 106

Slide 106 text

Creating Sources Flowable.fromCallable(() -> "Hello");
 
 Observable.fromCallable(() -> "Hello");
 
 Maybe.fromCallable(() -> "Hello");
 
 Single.fromCallable(() -> "Hello");
 
 Completable.fromCallable(() -> "Ignored!");

Slide 107

Slide 107 text

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"));

Slide 108

Slide 108 text

Creating Sources Observable.create();

Slide 109

Slide 109 text

Creating Sources Observable.create(new ObservableOnSubscribe() {
 @Override
 public void subscribe(ObservableEmitter e) throws Exception {
 e.onNext("Hello");
 e.onComplete();
 }X
 });

Slide 110

Slide 110 text

Creating Sources Observable.create(new ObservableOnSubscribe() {
 @Override
 public void subscribe(ObservableEmitter e) throws Exception {
 e.onNext("Hello");
 e.onComplete();
 }X
 });

Slide 111

Slide 111 text

Creating Sources Observable.create(new ObservableOnSubscribe() {
 @Override
 public void subscribe(ObservableEmitter e) throws Exception {
 e.onNext("Hello");
 e.onComplete();
 }X
 });

Slide 112

Slide 112 text

Creating Sources Observable.create(new ObservableOnSubscribe() {
 @Override
 public void subscribe(ObservableEmitter e) throws Exception {
 e.onNext("Hello");
 e.onComplete();
 }X
 });

Slide 113

Slide 113 text

Creating Sources Observable.create(e -> {
 e.onNext("Hello");
 e.onComplete();
 });

Slide 114

Slide 114 text

Creating Sources Observable.create(e -> {
 e.onNext("Hello"); e.onNext("World");
 e.onComplete();
 });

Slide 115

Slide 115 text

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 });
 });

Slide 116

Slide 116 text

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 });
 });

Slide 117

Slide 117 text

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 });
 });

Slide 118

Slide 118 text

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 });
 });

Slide 119

Slide 119 text

Creating Sources View view = // … Observable.create(e -> { e.setCancelation(() -> view.setOnClickListener(null)); view.setOnClickListener(v -> e.onNext(v));
 });

Slide 120

Slide 120 text

Creating Sources Flowable.create(e -> { … }); Observable.create(e -> { … }); Maybe.create(e -> { … }); Single.create(e -> { … }); Completable.create(e -> { … });

Slide 121

Slide 121 text

Observing Sources

Slide 122

Slide 122 text

Observing Sources Observable Flowable interface Subscriber {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Subscription s);
 }B interface Observer {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Disposable d);
 }B

Slide 123

Slide 123 text

Observing Sources Observable Flowable interface Subscriber {
 void onNext(T t);
 void onComplete();
 void onError(Throwable t);
 void onSubscribe(Subscription s);
 }B interface Observer {
 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

Slide 124

Slide 124 text

Observing Sources Observable o = Observable.just("Hello"); o.subscribe(new Observer() {
 @Override public void onNext(String s) { … }
 @Override public void onComplete() { … }
 @Override public void onError(Throwable t) { … } 
 @Override public void onSubscribe(Disposable d) { ??? }B
 }); Flowable interface Subscriber {
 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


Slide 125

Slide 125 text

Observing Sources Observable o = Observable.just("Hello"); o.subscribe(new DisposableObserver() {
 @Override public void onNext(String s) { … }
 @Override public void onComplete() { … }
 @Override public void onError(Throwable t) { … }
 }); 
 
 
 
 @Override public void onSubscribe(Disposable d) { ??? }B


Slide 126

Slide 126 text

Observing Sources Observable o = Observable.just("Hello"); o.subscribe(new DisposableObserver() {
 @Override public void onNext(String s) { … }
 @Override public void onComplete() { … }
 @Override public void onError(Throwable t) { … }
 });Z // TODO how do we dispose???

Slide 127

Slide 127 text

Observing Sources Observable o = Observable.just("Hello"); DisposableObserver observer = new DisposableObserver() {
 @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??????

Slide 128

Slide 128 text

Observing Sources Observable o = Observable.just("Hello"); DisposableObserver observer = new DisposableObserver() {
 @Override public void onNext(String s) { … }
 @Override public void onComplete() { … }
 @Override public void onError(Throwable t) { … }
 } o.subscribe(observer);Z observer.dispose();

Slide 129

Slide 129 text

Observing Sources Observable o = Observable.just("Hello"); o.subscribe(new DisposableObserver() {
 @Override public void onNext(String s) { … }
 @Override public void onComplete() { … }
 @Override public void onError(Throwable t) { … }
 });Z

Slide 130

Slide 130 text

Observing Sources Observable o = Observable.just("Hello"); o.subscribeWith(new DisposableObserver() {
 @Override public void onNext(String s) { … }
 @Override public void onComplete() { … }
 @Override public void onError(Throwable t) { … }
 });Z

Slide 131

Slide 131 text

Observing Sources Observable o = Observable.just("Hello"); Disposable d = o.subscribeWith(new DisposableObserver() {
 @Override public void onNext(String s) { … }
 @Override public void onComplete() { … }
 @Override public void onError(Throwable t) { … }
 });Z d.dispose();

Slide 132

Slide 132 text

Observing Sources Observable o = Observable.just("Hello"); CompositeDisposable disposables = new CompositeDisposable(); disposables.add(o.subscribeWith(new DisposableObserver() {
 @Override public void onNext(String s) { … }
 @Override public void onComplete() { … }
 @Override public void onError(Throwable t) { … }
 }));Z disposables.dispose(); 
 
 
 
 d.dispose(); Disposable d =

Slide 133

Slide 133 text

Observing Sources Observable o = Observable.just("Hello"); o.subscribeWith(new DisposableObserver() { … });Z Maybe m = Maybe.just("Hello"); m.subscribeWith(new DisposableMaybeObserver() { … });Z Single s = Single.just("Hello"); s.subscribeWith(new DisposableSingleObserver() { … });Z Completable c = Completable.completed(); c.subscribeWith(new DisposableCompletableObserver() { … });Z disposables.add(
 @Override public void onNext(String s) { … }
 @Override public void onComplete() { … }
 @Override public void onError(Throwable t) { … }
 ) disposables.dispose();

Slide 134

Slide 134 text

Observing Sources Flowable f = Flowable.just("Hello"); f.subscribeWith(new DisposableSubscriber() { … }); Observable o = Observable.just("Hello"); o.subscribeWith(new DisposableObserver() { … }); Maybe m = Maybe.just("Hello"); m.subscribeWith(new DisposableMaybeObserver() { … }); Single s = Single.just("Hello"); s.subscribeWith(new DisposableSingleObserver() { … }); Completable c = Completable.completed(); c.subscribeWith(new DisposableCompletableObserver() { … });

Slide 135

Slide 135 text

Observing Sources Flowable f = Flowable.just("Hello"); f.subscribeWith(new DisposableSubscriber() { … }); Observable o = Observable.just("Hello"); o.subscribeWith(new DisposableObserver() { … }); Maybe m = Maybe.just("Hello"); m.subscribeWith(new DisposableMaybeObserver() { … }); Single s = Single.just("Hello"); s.subscribeWith(new DisposableSingleObserver() { … }); Completable c = Completable.completed(); c.subscribeWith(new DisposableCompletableObserver() { … });

Slide 136

Slide 136 text

Observing Sources Flowable f = Flowable.just("Hello"); Disposable d1 = f.subscribeWith(new DisposableSubscriber() { … }); Observable o = Observable.just("Hello"); Disposable d2 = o.subscribeWith(new DisposableObserver() { … }); Maybe m = Maybe.just("Hello"); Disposable d3 = m.subscribeWith(new DisposableMaybeObserver() { … }); Single s = Single.just("Hello"); Disposable d4 = s.subscribeWith(new DisposableSingleObserver() { … }); Completable c = Completable.completed(); Disposable d5 = c.subscribeWith(new DisposableCompletableObserver() { … });

Slide 137

Slide 137 text

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.

Slide 138

Slide 138 text

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.

Slide 139

Slide 139 text

Operators

Slide 140

Slide 140 text

Operators • Manipulate or combine data in some way.

Slide 141

Slide 141 text

Operators • Manipulate or combine data in some way. • Manipulate threading in some way.

Slide 142

Slide 142 text

Operators • Manipulate or combine data in some way. • Manipulate threading in some way. • Manipulate emissions in some way.

Slide 143

Slide 143 text

Operators String greeting = "Hello";

Slide 144

Slide 144 text

Operators String greeting = "Hello";Z String yelling = greeting.toUppercase();

Slide 145

Slide 145 text

Operators Observable greeting = Observable.just("Hello");Z String yelling = greeting.toUppercase();Y

Slide 146

Slide 146 text

Operators Observable greeting = Observable.just("Hello"); Observable yelling = greeting.map(s -> s.toUppercase());Y

Slide 147

Slide 147 text

Operators Observable greeting = Observable.just("Hello"); Observable yelling = greeting.map(s -> s.toUppercase());Y

Slide 148

Slide 148 text

Operators @Override public void success() { runOnUiThread(new Runnable() { @Override public void run() { tv.setText(um.getUser().toString()); }4 }); }A

Slide 149

Slide 149 text

Operators Observable user = um.getUser();

Slide 150

Slide 150 text

Operators Observable user = um.getUser(); Observable mainThreadUser = user.observeOn(AndroidSchedulers.mainThread());

Slide 151

Slide 151 text

Operators Observable user = um.getUser(); Observable mainThreadUser = user.observeOn(AndroidSchedulers.mainThread());

Slide 152

Slide 152 text

Operators OkHttpClient client = // … Request request = // … Response response = client.newCall(request).execute();

Slide 153

Slide 153 text

Operators OkHttpClient client = // … Request request = // … Observable response = Observable.fromCallable(() -> { return client.newCall(request).execute(); });

Slide 154

Slide 154 text

Operators OkHttpClient client = // … Request request = // … Observable response = Observable.fromCallable(() -> { return client.newCall(request).execute(); }); Observable backgroundResponse = response.subscribeOn(Schedulers.io());

Slide 155

Slide 155 text

Operators OkHttpClient client = // … Request request = // … Observable response = Observable.fromCallable(() -> { return client.newCall(request).execute(); }); Observable backgroundResponse = response.subscribeOn(Schedulers.io());

Slide 156

Slide 156 text

Operators OkHttpClient client = // … Request request = // … Observable response = Observable.fromCallable(() -> { return client.newCall(request).execute(); }); Observable backgroundResponse = response.subscribeOn(Schedulers.io());

Slide 157

Slide 157 text

Operators OkHttpClient client = // … Request request = // … Observable response = Observable.fromCallable(() -> { return client.newCall(request).execute(); }) .subscribeOn(Schedulers.io());Y

Slide 158

Slide 158 text

Operators OkHttpClient client = // … Request request = // … Observable response = Observable.fromCallable(() -> { return client.newCall(request).execute(); }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread());Y

Slide 159

Slide 159 text

Operators OkHttpClient client = // … Request request = // … Observable response = Observable.fromCallable(() -> { return client.newCall(request).execute(); }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .map(response -> response.body().string());Y

Slide 160

Slide 160 text

Operators OkHttpClient client = // … Request request = // … Observable response = Observable.fromCallable(() -> { return client.newCall(request).execute(); }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .map(response -> response.body().string());Y// NetworkOnMainThread!

Slide 161

Slide 161 text

Operators OkHttpClient client = // … Request request = // … Observable response = Observable.fromCallable(() -> { return client.newCall(request).execute(); }) .subscribeOn(Schedulers.io()) .map(response -> response.body().string()) // Ok! .observeOn(AndroidSchedulers.mainThread());Y// NetworkOnMainThread!

Slide 162

Slide 162 text

Operator Specialization

Slide 163

Slide 163 text

Operator Specialization Observable

Slide 164

Slide 164 text

Operator Specialization first() Observable

Slide 165

Slide 165 text

Operator Specialization first() Observable Observable

Slide 166

Slide 166 text

Operator Specialization 1 2 3 4 5 6 7 8 9 10 11 first() 1 Observable Observable

Slide 167

Slide 167 text

Operator Specialization 1 2 3 4 5 6 7 8 9 10 11 get(0) 1 List List

Slide 168

Slide 168 text

Operator Specialization first() Observable Observable

Slide 169

Slide 169 text

Operator Specialization first() Observable Single

Slide 170

Slide 170 text

Operator Specialization 1 2 3 4 5 6 7 8 9 10 11 first() 1 Observable Single

Slide 171

Slide 171 text

Operator Specialization first() Observable Single

Slide 172

Slide 172 text

Operator Specialization first() Observable Single NoSuchElementException

Slide 173

Slide 173 text

Operator Specialization first() Observable

Slide 174

Slide 174 text

Operator Specialization firstElement() Observable

Slide 175

Slide 175 text

Operator Specialization firstElement() Observable Maybe

Slide 176

Slide 176 text

Operator Specialization firstElement() Observable Maybe

Slide 177

Slide 177 text

Operator Specialization ignoreElements() Observable

Slide 178

Slide 178 text

Operator Specialization ignoreElements() Observable Completable

Slide 179

Slide 179 text

Operator Specialization 1 2 3 4 5 6 7 8 9 ignoreElements() Observable Completable

Slide 180

Slide 180 text

Operator Specialization ignoreElements() Flowable Completable

Slide 181

Slide 181 text

Operator Specialization firstElement() Flowable Maybe

Slide 182

Slide 182 text

Operator Specialization first() Flowable Single

Slide 183

Slide 183 text

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

Slide 184

Slide 184 text

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

Slide 185

Slide 185 text

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

Slide 186

Slide 186 text

Being Reactive

Slide 187

Slide 187 text

Being Reactive um.getUser()

Slide 188

Slide 188 text

Being Reactive um.getUser() .observeOn(AndroidSchedulers.mainThread())

Slide 189

Slide 189 text

Being Reactive um.getUser() .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableObserver() { @Override public void onNext(User user) { }1 @Override public void onComplete() { /* ignored */ } @Override public void onError(Throwable t) { /* crash or show */ } });

Slide 190

Slide 190 text

Being Reactive um.getUser() .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableObserver() { @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

Slide 191

Slide 191 text

Being Reactive disposables.add(um.getUser() .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableObserver() { @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

Slide 192

Slide 192 text

Being Reactive // onCreate disposables.add(um.getUser() .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableObserver() { @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();

Slide 193

Slide 193 text

Being Reactive um.setName("Jane Doe")

Slide 194

Slide 194 text

Being Reactive um.setName("Jane Doe") .subscribeOn(Schedulers.io())

Slide 195

Slide 195 text

Being Reactive um.setName("Jane Doe") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread())

Slide 196

Slide 196 text

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 });

Slide 197

Slide 197 text

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

Slide 198

Slide 198 text

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

Slide 199

Slide 199 text

Architecture

Slide 200

Slide 200 text

Architecture • Less allocation to create a stream. • Less overhead when subscribing to a stream.

Slide 201

Slide 201 text

RxJava 2

Slide 202

Slide 202 text

RxJava 2 • Build an app that reacts properly instead of copes desperately!

Slide 203

Slide 203 text

RxJava 2 • Build an app that reacts properly instead of copes desperately! • Final release scheduled for 2016-10-29.

Slide 204

Slide 204 text

Living with 1.x and 2.x class RxJavaInterop {
 static Flowable toV2Flowable(rx.Observable o) { … }
 static Observable toV2Observable(rx.Observable o) { … } static Maybe toV2Maybe(rx.Single s) { … } static Maybe toV2Maybe(rx.Completable c) { … }
 static Single toV2Single(rx.Single s) { … }
 static Completable toV2Completable(rx.Completable c) { … } 
 static rx.Observable toV1Observable(Publisher p) { … } static rx.Observable toV1Observable(Observable o, …) { … }
 static rx.Single toV1Single(Single o) { … } static rx.Single toV1Single(Maybe m) { … }
 static rx.Completable toV1Completable(Completable c) { … } static rx.Completable toV1Completable(Maybe m) { … }
 }X

Slide 205

Slide 205 text

Living with 1.x and 2.x class RxJavaInterop {
 static Flowable toV2Flowable(rx.Observable o) { … }
 static Observable toV2Observable(rx.Observable o) { … } static Maybe toV2Maybe(rx.Single s) { … } static Maybe toV2Maybe(rx.Completable c) { … }
 static Single toV2Single(rx.Single s) { … }
 static Completable toV2Completable(rx.Completable c) { … } 
 static rx.Observable toV1Observable(Publisher p) { … } static rx.Observable toV1Observable(Observable o, …) { … }
 static rx.Single toV1Single(Single o) { … } github.com/akarnokd/RxJava2Interop

Slide 206

Slide 206 text

dependencies {
 compile 'io.reactivex.rxjava2:rxjava:2.0.0-RC3'
 compile 'io.reactivex.rxjava2:rxandroid:2.0.0-RC1' // Optionally...
 compile 'com.github.akarnokd:rxjava2-interop:0.3.0' }

Slide 207

Slide 207 text

jakewharton jakewharton jakewharton twitter.com/ google.com/+ .com Exploring RxJava