Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RxJava on Android

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for Marco Fuhrich Marco Fuhrich
February 07, 2017

RxJava on Android

My talk for the Android Developer Group in Nuremberg

Demo code available here: https://github.com/mrcktz/RxJavaExamples

Avatar for Marco Fuhrich

Marco Fuhrich

February 07, 2017
Tweet

Other Decks in Technology

Transcript

  1. Asynchronous Programming on Android Why? • Application Performance • User

    Experience (non-blocking) How? • Handler, Messenger, Runnable (HaMeR Framework) • AsyncTask • Loader • Service • ...
  2. Reactive Programming and Android Apps live in a very asynchronous

    environment • Configuration changes • Unreliable networking • Broadcasts • User Input A constant flow of changes and events has to be dispatched and handled while staying responsive and resilient.
  3. RxJava, pants down! • Observables: Classes representing different types of

    sources of data • Observers: Classes that enable you to listen to those sources • Operators: Methods for modifying and composing streams and data CREATE STREAM LISTEN TO STREAM MODIFY/ COMBINE STREAM
  4. RxJava, pants down! • Observables: Classes representing different types of

    sources of data • Observers: Classes that enable you to listen to those sources • Operators: Methods for modifying and composing streams and data Flowable<T> and Observable<T> • the source of our data • synchronous or asynchronous • 0, 1 or n items can be emitted • terminates never or by calling onComplete() or onError()
  5. RxJava, pants down! • Observables: Classes representing different types of

    sources of data • Observers: Classes that enable you to listen to those sources • Operators: Methods for modifying and composing streams and data Flowable<T>: Handles backpressure, subscribe with: public void subscribe(Subscriber<T>); Observable<T>: No backpressure, subscribe with: public void subscribe(Observer<T>); Backpressure is the reactive way to deal with a common problem: An Observable emits items too fast for the Observer to consume it.
  6. RxJava, pants down! • Observables: Classes representing different types of

    sources of data • Observers: Classes that enable you to listen to those sources • Operators: Methods for modifying and composing streams and data Subscribe to a Flowable by implementing: public interface Subscriber<T> { public void onSubscribe(Subscription s); public void onNext(T t); public void onError(Throwable t); public void onComplete(); } Subscribe to an Observable by implementing: public interface Observer<T> { public void onSubscribe(Disposable d); public void onNext(T t); public void onError(Throwable t); public void onComplete(); }
  7. Flowable<T> and Observable<T> offer operators that allow you to •

    manipulate data • manipulate threads (schedulers) • manipulate emission of data RxJava, pants down! • Observables: Classes representing different types of sources of data • Observers: Classes that enable you to listen to those sources • Operators: Methods for modifying and composing streams and data
  8. Whatever, now show me some code! Observable.just("Hello World").subscribe(System. out::println); This

    creates on Observable, subscribes to it and passes the String emitted through onNext(String next) to System.out.println.
  9. Create Data: Observables Observable.just("Hello World").subscribe(System. out::println); Create an Observable: Observable.just("Hello");

    Observable.just("Hello", "World"); Observable.fromArray(new int[]{1, 2, 3, 4}); Observable.fromCallable(() -> api.connect("email", "pass")); Observable.fromIterable(Arrays.asList(new int[]{1, 2, 3, 4})); Observable.fromFuture(() -> api.connect("email", "pass")); Or get all the freedom by using Observable.create(): Observable.create(e -> { e.onNext("Hello"); e.onNext("World"); e.onComplete() ; });
  10. Create Data: Observables Observable.just("Hello World").subscribe(System. out::println); There are special types

    of sources: Maybe, Single and Completable Maybe.fromRunnable(() -> System. out.println("Hello World")); Maybe.fromAction(() -> System. out.println("Hello World")); Completable.fromRunnable(() -> System. out.println("Completed!")); Completable.fromAction(() -> System. out.println("Completed!")); Completable: onComplete() or onError() will be called. Maybe: onSuccess(T t) or onComplete() or onError() Single: onSuccess(T t) or onError() will be called.
  11. Listen To Data: Subscribe Observable.just("Hello World").subscribe(System. out::println); Observable.just("Hello World").subscribe(new DisposableObserver<String>()

    { @Override public void onNext(String value) { System.out.println(value); } @Override public void onError(Throwable e) { ... } @Override public void onComplete() { ... } });
  12. Listen To Data: Subscribe Observable<User> userObservable = Observable.fromCallable(() -> api.getUserByMail(

    "[email protected]")); userObservable.subscribe( user -> helloTextView.setText("Hi" + user.nickname + "!"); );
  13. Listen To Data: Subscribe Observable<User> userObservable = Observable.fromCallable(() -> api.getUserByMail(

    "[email protected]")); userObservable.subscribe( user -> helloTextView.setText( "Hi" + user.nickname + "!"); ); Problems: • Potentially long running network operation! • We may not need the result anymore • Memory leaks
  14. Listen To Data: Subscribe CompositeDisposable disposables = new CompositeDisposable() ;

    Observable<User> userObservable = Observable.fromCallable(() -> api.getUserByMail( "[email protected]")); DisposableObserver<User> disposable = userObservable.subscribeWith ( user -> helloTextView.setText( "Hi" + user.nickname + "!"); ); disposables.add(disposable) ;
  15. Listen To Data: Subscribe You can now dispose the Observer

    whenever it’s appropriate: @Override protected void onDestroy() { disposables.dispose(); }
  16. Listen To Data: Subscribe Observable<User> userObservable = Observable.fromCallable(() -> api.getUserByMail(

    "[email protected]")); userObservable.subscribe( user -> helloTextView.setText( "Hi" + user.nickname + "!"); ); Problems: • Potentially long running network operation! • We may not need the result anymore • Memory leaks • NetworkOnMainThreadException
  17. Schedulers userObservable .observeOn(Schedulers.io()) .subscribeOn(AndroidSchedulers.mainThread()) .subscribeWith( user -> helloTextView.setText("Hi" + user.nickname

    + "!"; ); observeOn(Schedulers.io()): Networking will run in a background thread taken from the Thread pool of Schedulers.io() subscribeOn(AndroidSchedulers.mainThread()): All work that the Observer does will be done on the MainThread
  18. Modify / Combine Data: Operators List<String> searchTerms = Arrays. asList("Wh",

    "Obama", "Trump", "w", "Tr"); Observable.fromIterable(searchTerms) // Filter the search terms .filter(s -> s.length() > 2) // Create new SearchRequests from those search terms .flatMap(s -> Observable. just(new SearchRequest(s , time))) // Reduce the results to a single StringBuilder object .reduce(new StringBuilder() , (stringBuilder , searchRequest) -> stringBuilder.append(searchRequest.result())) // Print out the result .subscribe(System. out::print, e -> e.printStackTrace()) ;
  19. Modify / Combine Data: Operators • There are a lot

    of useful operators available • It’s not always obvious what they are doing • RxMarbles were invented to visualize the operations
  20. Example: Button clicks per second RxView.clicks(clickButton ) .buffer( 1, TimeUnit.SECONDS)

    .filter((clicks) -> clicks.size() > 0)) .subscribe((count) -> System. out.println(count + " clicks/s" )); Do not forget to dispose as there’s a strong reference to clickButton.
  21. Example: Form Validation First Step: Create data Flowable<Boolean> emailObservable =

    RxTextView.textChanges(mEmailView) .flatMap((chars) -> Flowable.just(mEmailView.getText() != null && isEmailValid(mEmailView.getText().toString()))).skip(1); Flowable<Boolean> passwordObservable = RxTextView.textChanges(mPasswordView) .flatMap((chars) -> Flowable.just(mPasswordView.getText() != null && isPasswordValid(mPasswordView.getText().toString()))).skip(1);
  22. Example: Form Validation Second Step: Modify / Combine data Flowable.combineLatest(emailObservable

    , passwordObservable , (emailValid, passwordValid) -> { if (!emailValid) { mEmailView.setError("Email invalid" ); } if (!passwordValid) { mPasswordView.setError("Password invalid" ); } return emailValid && passwordValid ; }).subscribeWith( mFormValidationDisposable );
  23. Example: Form Validation Third Step: Listen to data mFormValidationDisposable =

    new DisposableSubscriber<Boolean>() { @Override public void onNext(Boolean formValid) { mEmailSignInButton .setEnabled(formValid) ; } @Override public void onError(Throwable t) { /* Error */ } @Override public void onComplete() { /* Completed */ } }; Flowable.combineLatest(...).subscribeWith( mFormValidationDisposable );
  24. Other Real-World examples and their operators (taken from Kaushik Gopals

    open source effort to collect good samples for RxJava usecases) • Instant/Auto searching text listeners (using Subjects & debounce) • Two-way data binding (using PublishSubject) • Polling (using interval and repeatWhen) • Exponential backoff (using delay and retryWhen) • Eventbus (using RxRelay and debounceBuffer) • Orchestrating Observable: make parallel network calls, then combine the result into a single data point (using flatmap & zip) …. https://github.com/kaushikgopal/RxJava-Android-Samples
  25. Sources and Resources • Adopting RxJava on Airbnb Android http://de.droidcon.com/sites/global.droidcon.cod.newthinking.net/files/media/documents/Adopting%20RxJav

    a%20on%20Airbnb%20Android_0.pdf • Exploring RxJava 2 for Android • Jake Wharton https://www.youtube.com/watch?v=htIXKI5gOQU • Functional Reactive Programming with RxJava • Ben Christensen https://www.youtube.com/watch?v=_t06LRX0DV0&list=PLMacYHge0ewNw-VoFwXbNs9vCyvJumGnV • Learning RxJava for Android by example https://github.com/kaushikgopal/RxJava-Android-Samples • Fragmented Podcast: 004: The RxJava show with Dan Lew (Part 2) http://fragmentedpodcast.com/episodes/4/ • Reactivex.io: Documentation (Marbles!) http://reactivex.io/documentation/