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

Using Reactive Extensions for Java

Using Reactive Extensions for Java

An introduction to RxJava. Touches on the fundamental concepts and gives a concrete example of how you could use RxJava.

Etienne Lawlor

January 11, 2018
Tweet

More Decks by Etienne Lawlor

Other Decks in Technology

Transcript

  1. Android Developers Los Angeles RxJava is a Java VM implementation

    of ReactiveX (Reactive Extensions): a library for composing asynchronous and event-based programs by using observable sequences
  2. Android Developers Los Angeles • Observables emit a stream of

    data or events • Observers act upon the emitted items
  3. Android Developers Los Angeles • filter() - emits only those

    items from an Observable that pass a predicate test
  4. Android Developers Los Angeles • map() - transforms the items

    emitted by an Observable by applying a function to each item
  5. Android Developers Los Angeles • flatMap() - transforms the items

    emitted by an Observable into Observables, then flatten the emissions from those into a single Observable
  6. Android Developers Los Angeles • concatMap() - similar to flatMap(),

    but it transforms only a single source event at a time. Therefore, it guarantees that the items emitted in the resulting stream maintain the same order and will not be interleaved.
  7. Android Developers Los Angeles • concat() - emits the emissions

    from two or more Observables without interleaving them
  8. Android Developers Los Angeles • combineLatest() - when an item

    is emitted by either of two Observables, combine the latest item emitted by each Observable via a specified function and emit items based on the results of this function
  9. Android Developers Los Angeles • zip() - combines the emissions

    of multiple Observables together via a specified function and emit single items for each combination based on the results of this function
  10. Android Developers Los Angeles • debounce() - only emits an

    item from an Observable if a particular timespan has passed without it emitting another item
  11. /** * Provides a mechanism for receiving push-based notifications. *

    <p> * After an Observer calls an Observable's subscribe() method, the Observable calls the Observer's * onNext() method to provide notifications. A well-behaved Observable will call an Observer's * onCompleted() method exactly once or the Observer’s onError() method exactly once. * * @see <a href="http://reactivex.io/documentation/observable.html">ReactiveX documentation: Observable</a> * @param <T> the type of item the Observer expects to observe */ public interface Observer<T> { /** * Notifies the Observer that the Observable has finished sending push-based notifications. * The Observable will not call this method if it calls onError(). */ void onCompleted(); /** * Notifies the Observer that the Observable has experienced an error condition. * If the Observable calls this method, it will not thereafter call onNext() or * onCompleted(). * * @param e the exception encountered by the Observable */ void onError(Throwable e); /** * Provides the Observer with a new item to observe. * The Observable may call this method 0 or more times. * The Observable will not call this method again after it calls either onCompleted() or * onError(). * * @param t the item emitted by the Observable */ void onNext(T t); }
  12. Android Developers Los Angeles • subscribeOn() operator specifies the Scheduler

    on which the Observable should operate. • observeOn() operator specifies the Scheduler that the Observable will use to send notifications to its observers. Schedulers • RxJava comes with several out of the box Schedulers to use with Observables, such as Schedulers.io() (for blocking I/O operations), Schedulers.computation() (computational work) and Schedulers.newThread() (creates new thread for the work).
  13. Android Developers Los Angeles • Do not display errors for

    an empty email input field. Check #1 • If there currently is an error immediately clear it as the email input field changes. • If the user starts typing, don’t immediately check for validity but instead wait for 400 ms to pass after the last change was made to the email input field. • If the validity check returns true clear the error view from the email input field, otherwise display the error view on the email input field.
  14. Observable<CharSequence> emailChangeObservable = RxTextView.textChanges(emailEditText); 
 Subscription emailSubscription = emailChangeObservable .doOnNext(new

    Action1<CharSequence>() { @Override public void call(CharSequence charSequence) { hideEmailError(); } }) .debounce(400, TimeUnit.MILLISECONDS) .filter(new Func1<CharSequence, Boolean>() { @Override public Boolean call(CharSequence charSequence) { return !TextUtils.isEmpty(charSequence); } }) .observeOn(AndroidSchedulers.mainThread()) // UI Thread .subscribe(new Subscriber<CharSequence>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { e.printStackTrace(); } @Override public void onNext(CharSequence charSequence) { boolean isEmailValid = validateEmail(charSequence.toString()); if (!isEmailValid) { showEmailError(); } else { hideEmailError(); } } });
  15. Android Developers Los Angeles • Do not display errors for

    an empty password input field. Check #2 • If there currently is an error immediately clear it as the password input field changes. • If the user starts typing, don’t immediately check for validity but instead wait for 400 ms to pass after the last change was made to the password input field. • If the validity check returns true clear the error view from the password input field, otherwise display the error view on the password input field.
  16. Observable<CharSequence> passwordChangeObservable = RxTextView.textChanges(passwordEditText); Subscription passwordSubscription = passwordChangeObservable .doOnNext(new Action1<CharSequence>()

    { @Override public void call(CharSequence charSequence) { hidePasswordError(); } }) .debounce(400, TimeUnit.MILLISECONDS) .filter(new Func1<CharSequence, Boolean>() { @Override public Boolean call(CharSequence charSequence) { return !TextUtils.isEmpty(charSequence); } }) .observeOn(AndroidSchedulers.mainThread()) // UI Thread .subscribe(new Subscriber<CharSequence>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { e.printStackTrace(); } @Override public void onNext(CharSequence charSequence) { boolean isPasswordValid = validatePassword(charSequence.toString()); if (!isPasswordValid) { showPasswordError(); } else { hidePasswordError(); } } });
  17. Android Developers Los Angeles • Do not enable the SignIn

    button until both the email input field and password input field are valid. Check #3
  18. Subscription signInFieldsSubscription = Observable.combineLatest(emailChangeObservable, passwordChangeObservable, new Func2<CharSequence, CharSequence, Boolean>() {

    @Override public Boolean call(CharSequence email, CharSequence password) { boolean isEmailValid = validateEmail(email.toString()); boolean isPasswordValid = validatePassword(password.toString()); return isEmailValid && isPasswordValid; } }) .observeOn(AndroidSchedulers.mainThread()) // UI Thread .subscribe(new Observer<Boolean>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { e.printStackTrace(); } @Override public void onNext(Boolean validFields) { if (validFields) { enableSignIn(); } else { disableSignIn(); } } });