The Next Step for Reactive Android Programming

Post on 17-Feb-2017

369 views 1 download

transcript

Reactive Android:The Next Steps

Futurice & upday

@tpolansk

Tomek Polanski

The Good

@tpolansk

Reactive Streamscompatibility

@tpolansk[1]

4 interfaces 7 methods

@tpolansk

Flowable.just("- I'm RxJava!")

@tpolansk

Flowable.just("- I'm RxJava!")

@tpolansk

RxJava 2

Flux.from(Flowable.just("- I'm RxJava!"))

@tpolansk

RxJava 2

Flux.from(Flowable.just("- I'm RxJava!"))

@tpolansk

RxJava 2

Reactor 3

Flux.from(Flowable.just("- I'm RxJava!")) .map(msg -> msg + " - I'm Reactor!")

@tpolansk

RxJava 2

Flux.from(Flowable.just("- I'm RxJava!")) .map(msg -> msg + " - I'm Reactor!")

@tpolansk

Reactor 3

RxJava 2

Flux.from(Flowable.just("- I'm RxJava!")) .map(msg -> msg + " - I'm Reactor!") .subscribe(msg -> print(msg));

@tpolansk

RxJava 2

Flux.from(Flowable.just("- I'm RxJava!")) .map(msg -> msg + " - I'm Reactor!") .subscribe(msg -> print(msg));

@tpolansk

RxJava 2

Reactor 3

[2]

Backpressure

@tpolansk

Backpressure

Flowable&

Observable@tpolansk

Flowable:BUFFER, DROP,…

@tpolansk

Observable:Buffer-like

@tpolansk

Observable:Buffer-like

@tpolansk

Out Of Memory

Flowable?

@tpolansk

@tpolansk

Flowable

Exception Is Really Likely

@tpolansk

Observable

Exception Is Not Likely

@tpolansk

Better Single and Completable

Integration @tpolansk

Observable.range(0, 10) .all(it -> it % 2 == 0)

@tpolansk

Observable.range(0, 10) .all(it -> it % 2 == 0)

@tpolansk

RxJava 1 - Observable

@tpolansk

RxJava 2 - Single

Observable.range(0, 10) .all(it -> it % 2 == 0)

Performance

@tpolansk[3]

Performance

(-76%, +2800%)

@tpolansk[3]

Memory

@tpolansk[3]

Memory

50% less

@tpolansk[3]

Testing

@tpolansk

Testing

.test()

@tpolansk

Observable.just(1)

@tpolansk

Observable.just(1) .test()

@tpolansk

Observable.just(1) .test() .assertValue(1)

@tpolansk

Observable.just(1) .test() .assertValue(1) .assertComplete();

@tpolansk

Observable.just(1) .test() .assertValue(1) .assertComplete();

@tpolansk

Soon in RxJava 1

[4]

Bye Bye nulls

@tpolansk

“1B$ Mistake” no more

[5]

The Bad

@tpolansk

Bye Bye nulls

@tpolansk

Removing takes time

Writing Operators

@tpolansk

10x HARDER*

@tpolansk[6]

10x HARDER*

@tpolansk

Android Dev’s Nightmare

@tpolansk

AsyncTask?

@tpolansk

AsyncTask?

@tpolansk

Configuration Change?

AsyncTask?

@tpolansk

Styling? Configuration Change?

AsyncTask?

@tpolansk

Styling? Bluetooth LE?

Configuration Change?

AsyncTask?

@tpolansk

Styling? Java 7 Forever?Bluetooth LE?

Configuration Change?

Dex Limit

@tpolansk

RxJava 1.2.2

5600 @tpolansk

RxJava 2.0.1

9200 @tpolansk

5600 + 9200 = 14800

@tpolansk

5600 + 9200 = 14800

22% Dex Limit @tpolansk

The Migration

@tpolansk

upday’s RxJava integration

@tpolansk

Observable: 1224

@tpolansk

Observable: 1224

@tpolansk

Observable: 1224int: 1516

@tpolansk

Observable: 1224int: 1516

@tpolansk

Observable: 1224int: 1516

String: 3246@tpolansk

Observable: 1224int: 1516

String: 3246@tpolansk

Not in One Go!

@tpolansk

Update toThe Newest

RxJava 1.x.x@tpolansk[7]

Use

RxJava2Interop@tpolansk[8]

The Data Flow

@tpolansk

@tpolansk

Network

UI

@tpolansk

Network

UI

@tpolansk

Network

UI

Start With Leafs

Not Roots

@tpolansk

// Activity

dataModel.getText() .subscribe(text -> view.setText(text));

@tpolansk

// Activity

dataModel.getText() .subscribe(text -> view.setText(text));

@tpolansk

RxJava 1

// Activity

RxJavaInterop .toV2Observable(dataModel.getText()) .subscribe(text -> view.setText(text));

@tpolansk

// Activity

RxJavaInterop .toV2Observable(dataModel.getText()) .subscribe(text -> view.setText(text));

@tpolansk

RxJava 1

// Activity

RxJavaInterop .toV2Observable(dataModel.getText()) .subscribe(text -> view.setText(text));

@tpolansk

RxJava 1

RxJava 2

// DataModel

Observable<String> getText() { return cache.getText();}

@tpolansk

// DataModel

Observable<String> getText() { return cache.getText();}

@tpolansk

RxJava 1

// DataModel

Observable<String> getText() { return RxJavaInterop .toV2Observable(cache.getText());}

@tpolansk

// DataModel

Observable<String> getText() { return RxJavaInterop .toV2Observable(cache.getText());}

@tpolansk

RxJava 2

// Activity

RxJavaInterop .toV2Observable(dataModel.getText()) .subscribe(text -> view.setText(text));

@tpolansk

RxJava 2

// Activity

dataModel.getText() .subscribe(text -> view.setText(text));

@tpolansk

RxJava 2

Replacing nulls

@tpolansk

Replacing nulls

Null Objects or

Optionals@tpolansk[9]

class User {String name;

User(String name) {this.name = name;

}}

@tpolansk

Observable<User> userStream = …

@tpolansk

Observable<User> userStream = ……userStream .filter(user -> user != null)

@tpolansk

class User {static final User EMPTY = new

User(“”);

String name;

public User(String name) {this.name = name;

}}

@tpolansk

Observable<User> userStream = ……userStream .filter(user -> !user.equals(User.EMPTY))

@tpolansk

The Frustrating

@tpolansk

NoSuchMethodError

@tpolansk

NoSuchMethodError

@tpolansk

Wait for libs update!

@tpolansk

First element?

@tpolansk

.first(…).firstOrError()

.singleElement()

.single(…)

.singleOrError()

.firstElement()

@tpolansk

.first(…).firstOrError()

.singleElement()

.single(…)

.singleOrError()

.firstElement()

?

@tpolansk

Relearn some operators

!

Migrating Tests

@tpolansk

TestSubscriber<Integer> ts = new TestSubscriber<>();

Observable.just(1).subscribe(ts);

ts.assertValue(1);

@tpolansk

TestSubscriber<Integer> ts = new TestSubscriber<>();

Observable.just(1).subscribe(ts);

ts.assertValue(1);

@tpolansk

TestObserver<Integer> to = new TestObserver<>();

Observable.just(1).subscribe(to);

to.assertValue(1);

@tpolansk

Observable.just(1) .test() .assertValue(1);

@tpolansk

Conclusion

@tpolansk

RxJava 2 Is Better!

@tpolansk

New Project?

Definitely RxJava 2

@tpolansk

Almost Done Project?

Should Not Migrate

@tpolansk

Anything Between?

It’s Always Up to You

@tpolansk

@tpolansk

[1] Reactive Streams – https://github.com/reactive-streams/reactive-streams-jvm[2] Reactor 3 - https://github.com/reactor/reactor-core[3] RxJava 2 Benchmark - https://github.com/akarnokd/akarnokd-misc/issues/2[4] test() operator in v1 - https://github.com/ReactiveX/RxJava/pull/4777[5] The Billion Dollar Mistake - https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare [6] Writing Operators - https://github.com/ReactiveX/RxJava/wiki/Writing-operators-for-2.0[7] RxJava releases - https://github.com/ReactiveX/RxJava/releases[8] RxJava2Interop - https://github.com/akarnokd/RxJava2Interop[9] Simple Options - https://github.com/tomaszpolanski/Options