Slide 1

Slide 1 text

Managing The Reactive World Jake Wharton

Slide 2

Slide 2 text

Managing The Reactive World (with RxJava) 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 System.out.println(um.getUser()); 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

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? GET / 200 OK SELECT * Jane Doe setText onClick SELECT * Jane Doe setText UPDATE user Jane Doe setText

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 must be designed for.

Slide 62

Slide 62 text

Flowable vs. Observable • Backpressure must be designed for.

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

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

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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

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

Slide 94

Slide 94 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 95

Slide 95 text

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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

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


Slide 98

Slide 98 text

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

Slide 99

Slide 99 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 100

Slide 100 text

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

Slide 101

Slide 101 text

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

Slide 102

Slide 102 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 103

Slide 103 text

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

Slide 104

Slide 104 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 105

Slide 105 text

Creating Sources Observable.create();

Slide 106

Slide 106 text

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

Slide 107

Slide 107 text

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

Slide 108

Slide 108 text

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

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(e -> {
 e.onNext("Hello");
 e.onComplete();
 }); new ObservableOnSubscribe()
 @Override
 public void subscribe(ObservableEmitter ) throws Exception {
 
 
 }X


Slide 111

Slide 111 text

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

Slide 112

Slide 112 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 });
 }); 
 e.onNext("Hello"); e.onNext("World");
 e.onComplete();

Slide 113

Slide 113 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 114

Slide 114 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 });
 }); 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 115

Slide 115 text

Creating Sources View view = // … Observable.create(e -> { e.setCancelation(() -> view.setOnClickListener(null)); view.setOnClickListener(v -> e.onNext(v));
 }); OkHttpClient client = // ... Request request = // ... 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 116

Slide 116 text

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

Slide 117

Slide 117 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 118

Slide 118 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 119

Slide 119 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 120

Slide 120 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 121

Slide 121 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 122

Slide 122 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 123

Slide 123 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 124

Slide 124 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 125

Slide 125 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 126

Slide 126 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 127

Slide 127 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 128

Slide 128 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 129

Slide 129 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() { … }); 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 130

Slide 130 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 131

Slide 131 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 132

Slide 132 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 133

Slide 133 text

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

Slide 134

Slide 134 text

Operators String greeting = "Hello";

Slide 135

Slide 135 text

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

Slide 136

Slide 136 text

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

Slide 137

Slide 137 text

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

Slide 138

Slide 138 text

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

Slide 139

Slide 139 text

Operators String greeting = "Hello, World!";

Slide 140

Slide 140 text

Operators String greeting = "Hello, World!";Z String[] words = greeting.split(" ");

Slide 141

Slide 141 text

Operators Observable greeting = Observable.just("Hello, World!");Z String[] words = greeting.split(" ");Y

Slide 142

Slide 142 text

Operators Observable greeting = Observable.just("Hello, World!");Z Observable words = greeting.map(s -> s.split(" "));Y

Slide 143

Slide 143 text

Operators Observable greeting = Observable.just("Hello, World!");Z Observable> words = greeting.map(s -> Observable.fromArray(s.split(" ")));Y

Slide 144

Slide 144 text

Operators Observable greeting = Observable.just("Hello, World!");Z Observable words = greeting.flatMap(s -> Observable.fromArray(s.split(" ")));Y Observable< > map

Slide 145

Slide 145 text

Operators Observable greeting = Observable.just("Hello, World!"); Observable words = greeting.flatMap(s -> Observable.fromArray(s.split(" ")));

Slide 146

Slide 146 text

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

Slide 147

Slide 147 text

Operators Observable user = um.getUser();

Slide 148

Slide 148 text

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

Slide 149

Slide 149 text

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

Slide 150

Slide 150 text

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

Slide 151

Slide 151 text

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

Slide 152

Slide 152 text

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

Slide 153

Slide 153 text

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

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(); }) .subscribeOn(Schedulers.io());Y

Slide 156

Slide 156 text

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

Slide 157

Slide 157 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 158

Slide 158 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 159

Slide 159 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 160

Slide 160 text

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

Slide 161

Slide 161 text

Operator Specialization Observable

Slide 162

Slide 162 text

Operator Specialization first() Observable

Slide 163

Slide 163 text

Operator Specialization first() Observable Observable

Slide 164

Slide 164 text

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

Slide 165

Slide 165 text

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

Slide 166

Slide 166 text

Operator Specialization first() Observable Single

Slide 167

Slide 167 text

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

Slide 168

Slide 168 text

Operator Specialization first() Observable Single NoSuchElementException

Slide 169

Slide 169 text

Operator Specialization firstElement() Observable Maybe

Slide 170

Slide 170 text

Operator Specialization firstElement() Observable Maybe

Slide 171

Slide 171 text

Operator Specialization ignoreElements() Observable Completable

Slide 172

Slide 172 text

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

Slide 173

Slide 173 text

Operator Specialization ignoreElements() Flowable Completable

Slide 174

Slide 174 text

Operator Specialization firstElement() Flowable Maybe

Slide 175

Slide 175 text

Operator Specialization first() Flowable Single

Slide 176

Slide 176 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 177

Slide 177 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 178

Slide 178 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 179

Slide 179 text

Being Reactive um.getUser()

Slide 180

Slide 180 text

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

Slide 181

Slide 181 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 182

Slide 182 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 183

Slide 183 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 184

Slide 184 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 185

Slide 185 text

Being Reactive um.setName("Jane Doe")

Slide 186

Slide 186 text

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

Slide 187

Slide 187 text

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

Slide 188

Slide 188 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 189

Slide 189 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 190

Slide 190 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 191

Slide 191 text

Java 9 • JEP 266: More Concurrency Updates

Slide 192

Slide 192 text

Java 9 • JEP 266: More Concurrency Updates Interfaces supporting the Reactive Streams publish-subscribe framework, nested within the new class Flow, along with a utility class SubmissionPublisher that developers can use to create custom components. These (very small) interfaces correspond to those defined with broad participation (from the Reactive Streams initiative) and support interoperability across a number of async systems running on JVMs. Nesting the interfaces within a class is a conservative policy allowing their use across various short-term and long-term possibilities. The proposed java.util.concurrent components have been offered in pre-release since January 2015, and have benefitted from several rounds of review. There are no plans to provide network- or I/O-based java.util.concurrent components for distributed messaging, but it is possible that future JDK releases will include such APIs in other packages.

Slide 193

Slide 193 text

final class Flow { private Flow() {} interface Publisher { void subscribe(Subscriber super T> subscriber); } interface Subscriber { void onSubscribe(Subscription subscription); void onNext(T item); void onError(Throwable throwable); void onComplete(); } interface Subscription { void request(long n); void cancel(); } interface Processor extends Subscriber, Publisher { } }

Slide 194

Slide 194 text

jakes.link/rx-state

Slide 195

Slide 195 text

jakewharton jakewharton jakewharton twitter.com/ github.com/ .com Managing The Reactive World