Intro to RxJava/RxAndroid - GDG Munich Android

39
INTRO TO RXJAVA & RXANDROID Egor Andreevici

Transcript of Intro to RxJava/RxAndroid - GDG Munich Android

Page 1: Intro to RxJava/RxAndroid - GDG Munich Android

INTRO TO RXJAVA& RXANDROID

Egor Andreevici

Page 2: Intro to RxJava/RxAndroid - GDG Munich Android

WHAT? HOW? WHY?

& A DEMO

Page 3: Intro to RxJava/RxAndroid - GDG Munich Android

WHAT IS RXJAVA?

Page 4: Intro to RxJava/RxAndroid - GDG Munich Android

“RXJAVA IS A JAVA VM IMPLEMENTATION OF REACTIVEX (REACTIVE EXTENSIONS): A LIBRARY FOR COMPOSING ASYNCHRONOUS AND EVENT-BASED PROGRAMS BY USING OBSERVABLE SEQUENCES.”

RxJava Wiki

WHAT IS RXJAVA?

Page 5: Intro to RxJava/RxAndroid - GDG Munich Android

WHAT IS RXJAVA?

OBSERVABLES (AND MARBLE DIAGRAMS)

Page 6: Intro to RxJava/RxAndroid - GDG Munich Android

WHAT IS RXJAVA?

PROGRAM STRUCTURE

subscription = Observable .create(…) .transform(…) .subscribe(...);

Page 7: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

Page 8: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

THE HIGH LEVEL PLAN

▸ Create an Observable

▸ Manipulate data using operators

▸ Subscribe and consume

▸ Profit!

Page 9: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

CREATING OBSERVABLES: CREATE()

Observable.create(subscriber -> { try { for (int value = 1; value <= 3; value++) { subscriber.onNext(value); } subscriber.onCompleted(); } catch (Throwable t) { subscriber.onError(t); }});

Page 10: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

THE OBSERVER INTERFACE

public interface Observer<T> {

void onCompleted();

void onError(Throwable e);

void onNext(T t);}

Page 11: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

THE NOTIFICATIONS CONTRACT

▸ Zero or more onNext() notifications

▸ Either onCompleted() or onError(), not both!

▸ Nothing more!

▸ May never terminate

▸ May never call onCompleted()

▸ All notifications must be issued serially

Page 12: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

CREATING OBSERVABLES: JUST()

Observable.just(1);

Observable.just(1, 2);

Observable.just(1, 2, 3);

. . .

Observable.just(1, … , 9);

Page 13: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

CREATING OBSERVABLES: FROM()

Observable.from(Arrays.asList(1, 2, 3));

Observable.from(new Integer[]{1, 2, 3});

Page 14: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

CREATING OBSERVABLES: MISC

Observable.empty();

Observable.error(t);

Observable.never();

Page 15: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

Observable.create(subscriber -> { try { for (int i = 0; i < 10000; i++) { T value = longRunningNetworkRequest(); subscriber.onNext(value); } subscriber.onCompleted(); } catch (Throwable t) { subscriber.onError(t); }});

CAVEATS: HANDLING UNSUBSCRIBING

Page 16: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

SUBSCRIPTION INTERFACE

public interface Subscription {

void unsubscribe();

boolean isUnsubscribed();}

Page 17: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

CAVEATS: HANDLING UNSUBSCRIBING

Observable.create(subscriber -> { try { for (int i = 0; i < 10000; i++) { if (subscriber.isUnsubscribed()) { return; } T value = longRunningNetworkRequest(); subscriber.onNext(value); } subscriber.onCompleted(); } catch (Throwable t) { subscriber.onError(t); }});

Page 18: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

OPERATORS

▸ Transformational

▸ map()

▸ flatMap()

▸ concatMap()

▸ Filtering

▸ filter()

▸ take()

▸ skip()

▸ Combining

▸ merge()

▸ zip()

▸ combineLatest()

AND MANY MORE…

Page 19: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

OPERATORS: FILTER()

Page 20: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

OPERATORS: MAP()

Page 21: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

OPERATORS: FLATMAP()

Page 22: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

OPERATORS: ZIP()

Page 23: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

SUBSCRIBING TO OBSERVABLES

.subscribe( value -> renderValue(value), error -> renderError(error), () -> Log.d(LOGTAG, "Done!"));

Page 24: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

MULTITHREADING: OPERATORS

Observable<T> observeOn(Scheduler scheduler) {}

Observable<T> subscribeOn(Scheduler scheduler) {}

Page 25: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

MULTITHREADING: SCHEDULERS

Schedulers.io()

Schedulers.computation()

Schedulers.newThread()

Schedulers.from(Executor)

Page 26: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

TESTING: BLOCKING OBSERVABLES

@Testpublic void testingWithBlockingObservable() { Observable<Integer> intObservable =

Observable.just(1, 2, 3); BlockingObservable<Integer> blocking = intObservable.toBlocking(); assertThat(blocking.first()).isEqualTo(1); assertThat(blocking.last()).isEqualTo(3);

blocking.getIterator(); blocking.toIterable();}

Page 27: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

TESTING: TESTSUBSCRIBER

@Testpublic void testingWithTestSubscriber() { Observable<Integer> intObservable = Observable.just(1, 2, 3); TestSubscriber<Integer> testSubscriber = TestSubscriber.create();

intObservable.subscribe(testSubscriber);

testSubscriber.assertValues(1, 2, 3); testSubscriber.assertNoErrors(); testSubscriber.assertCompleted();}

Page 28: Intro to RxJava/RxAndroid - GDG Munich Android

HOW RXJAVA?

DEBUGGING: SIDE EFFECTS

Observable.just(1, 2, 3) .doOnNext(next -> append("Before filter: " + next))

.filter(value -> value % 2 == 0) .doOnNext(next -> append("After filter: " + next)) .subscribe(...);

Page 29: Intro to RxJava/RxAndroid - GDG Munich Android

RXJAVA ON ANDROID

Page 30: Intro to RxJava/RxAndroid - GDG Munich Android

RXJAVA ON ANDROID

RXANDROID

▸ Super tiny

▸ AndroidSchedulers.mainThread()

▸ HandlerScheduler.from(Handler)

Page 31: Intro to RxJava/RxAndroid - GDG Munich Android

RXJAVA ON ANDROID

RXBINDING

▸ RxJava binding APIs for Android's UI widgets

▸ RxView.clicks(…), RxView.enabled(…) etc.

▸ RxTextView.textChanges(…)

Page 32: Intro to RxJava/RxAndroid - GDG Munich Android

RXJAVA ON ANDROID

RXLIFECYCLE

▸ Lifecycle handling APIs for Android apps using RxJava

▸ .compose(RxLifecycle.bindActivity(lifecycle))

▸ RxActivity, RxFragment

▸ .compose(bindToLifecycle())

Page 33: Intro to RxJava/RxAndroid - GDG Munich Android

RXJAVA ON ANDROID

RETROFIT: THE UGLY

@Overridepublic void onActivityCreated(Bundle savedInstanceState) {

super.onActivityCreated(savedInstanceState);

GithubApiClient client = createGithubApiClient();try {

List<Repo> repos = client.getRepos().execute().body();// render repos

} catch (IOException e) {// handle

}}

Page 34: Intro to RxJava/RxAndroid - GDG Munich Android

RXJAVA ON ANDROID

RETROFIT: THE BAD@Overridepublic void onActivityCreated(Bundle savedInstanceState) {

super.onActivityCreated(savedInstanceState);

GithubApiClient client = createGithubApiClient(); client.getRepos().enqueue(new Callback<List<Repo>>() {

@Overridepublic void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {

// render repos }

@Override public void onFailure(Call<List<Repo>> call, Throwable t) { // handle } });}

Page 35: Intro to RxJava/RxAndroid - GDG Munich Android

RXJAVA ON ANDROID

RETROFIT: THE GOOD

@Overridepublic void onActivityCreated(Bundle savedInstanceState) {

super.onActivityCreated(savedInstanceState);

GithubApiClient client = createGithubApiClient(); subscription = client.getRepos() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( repos -> renderRepos(repos), error -> handleError(error));}

Page 36: Intro to RxJava/RxAndroid - GDG Munich Android

WHY RXJAVA?

Page 37: Intro to RxJava/RxAndroid - GDG Munich Android

WHY RXJAVA?

WHY RXJAVA?

▸ Set of powerful operators

▸ Easy threading

▸ Explicit error handling

▸ Testable

▸ Lots of perks specific to Android

Page 38: Intro to RxJava/RxAndroid - GDG Munich Android

DEMO TIME!

Page 39: Intro to RxJava/RxAndroid - GDG Munich Android

THANK YOU!Egor Andreevici

blog.egorand.me · @EgorAnd · +EgorAndreevich