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

5 RxJava Tips You Might not Know

5 RxJava Tips You Might not Know

In this talk, I'm giving you 5 useful tips of RxJava you might not know.

Reference
- Subscriptions#empty()
http://reactivex.io/RxJava/javadoc/rx/subscriptions/Subscriptions.html#empty()
- SerialSubscription
http://reactivex.io/RxJava/javadoc/rx/subscriptions/SerialSubscription.html
- Observable#compose(Transformer)
http://reactivex.io/RxJava/javadoc/rx/Observable.html#compose(rx.Observable.Transformer)
- Observable.fromCallable(Callable)
http://reactivex.io/RxJava/javadoc/rx/Observable.html#fromCallable(java.util.concurrent.Callable)
- Don't break the chain: use RxJava's compose() operator
http://blog.danlew.net/2015/03/02/dont-break-the-chain/
- Loading data from multiple sources with RxJava
http://blog.danlew.net/2015/06/22/loading-data-from-multiple-sources-with-rxjava/
- dlew/rxjava-multiple-sources-sample: Sample code demonstrating loading multiple data sources via RxJava
https://github.com/dlew/rxjava-multiple-sources-sample/

Hiroshi Kurokawa

May 25, 2016
Tweet

More Decks by Hiroshi Kurokawa

Other Decks in Technology

Transcript

  1. 5 RXJAVA TIPS
    YOU MIGHT NOT KNOW
    HIROSHI KUROKAWA (FABLIC, INC.)
    POTATOTIPS #29, MAY 25TH, 2016

    View full-size slide

  2. POTATOTIPS #29 (2016-05-25)
    1. AVOID NULL CHECK FOR SUBSCRIPTION - SINGLE
    private Subscription signInSubscription = null;
    private void sendSignInRequest() {
    signInSubscription = service.signInUser(new SignInRequest(email, password))
    .subscribe(...);
    }
    @Override
    public void onDestroy() {
    if (signInSubscription != null) {
    signInSubscription.unsubscribe();
    }
    super.onDestroy();
    }
    ▸ In RxJava, it’s really important to call unsubscribe()
    ▸ If you forgot it, memory leak would occur

    View full-size slide

  3. POTATOTIPS #29 (2016-05-25)
    1. AVOID NULL CHECK FOR SUBSCRIPTION - SINGLE
    private Subscription signInSubscription = null;
    private void sendSignInRequest() {
    signInSubscription = service.signInUser(new SignInRequest(email, password))
    .subscribe(...);
    }
    @Override
    public void onDestroy() {
    if (signInSubscription != null) {
    signInSubscription.unsubscribe();
    }
    super.onDestroy();
    }
    ▸ In RxJava, it’s really important to call unsubscribe()
    ▸ If you forgot it, memory leak would occur

    View full-size slide

  4. POTATOTIPS #29 (2016-05-25)
    1. AVOID NULL CHECK FOR SUBSCRIPTION - SINGLE
    private Subscription subscription = null;
    private void sendSignInRequest() {
    subscription = service.signInUser(new SignInRequest(email, password))
    .subscribe(...);
    }
    @Override
    public void onDestroy() {
    if (subscription != null) {
    subscription.unsubscribe();
    }
    super.onDestroy();
    }

    View full-size slide

  5. POTATOTIPS #29 (2016-05-25)
    1. AVOID NULL CHECK FOR SUBSCRIPTION - SINGLE
    private Subscription subscription = null;
    private void sendSignInRequest() {
    subscription = service.signInUser(new SignInRequest(email, password))
    .subscribe(...);
    }
    @Override
    public void onDestroy() {
    if (subscription != null) {
    subscription.unsubscribe();
    }
    super.onDestroy();
    }
    Use Subscriptions.empty() instead

    View full-size slide

  6. POTATOTIPS #29 (2016-05-25)
    1. AVOID NULL CHECK FOR SUBSCRIPTION - SINGLE
    private Subscription subscription = null;
    private void sendSignInRequest() {
    subscription = service.signInUser(new SignInRequest(email, password))
    .subscribe(...);
    }
    @Override
    public void onDestroy() {
    if (subscription != null) {
    subscription.unsubscribe();
    }
    super.onDestroy();
    }

    View full-size slide

  7. POTATOTIPS #29 (2016-05-25)
    1. AVOID NULL CHECK FOR SUBSCRIPTION - SINGLE
    private Subscription subscription =
    private void sendSignInRequest() {
    subscription = service.signInUser(new SignInRequest(email, password))
    .subscribe(...);
    }
    @Override
    public void onDestroy() {
    if (subscription != null) {
    subscription.unsubscribe();
    }
    super.onDestroy();
    }

    View full-size slide

  8. POTATOTIPS #29 (2016-05-25)
    1. AVOID NULL CHECK FOR SUBSCRIPTION - SINGLE
    private Subscription subscription = Subscriptions.empty();
    private void sendSignInRequest() {
    subscription = service.signInUser(new SignInRequest(email, password))
    .subscribe(...);
    }
    @Override
    public void onDestroy() {
    if (subscription != null) {
    subscription.unsubscribe();
    }
    super.onDestroy();
    }

    View full-size slide

  9. POTATOTIPS #29 (2016-05-25)
    1. AVOID NULL CHECK FOR SUBSCRIPTION - SINGLE
    private Subscription subscription = Subscriptions.empty();
    private void sendSignInRequest() {
    subscription = service.signInUser(new SignInRequest(email, password))
    .subscribe(...);
    }
    @Override
    public void onDestroy() {
    subscription.unsubscribe();
    super.onDestroy();
    }

    View full-size slide

  10. POTATOTIPS #29 (2016-05-25)
    2. REPLACE AN EXISTING SUBSCRIPTION
    private Subscription subscription = Susbscriptions.empty();
    // can be called multiple times
    private void update() {
    // cancel the previous request if necessary
    if (!subscription.isUnsubscribed()) {
    subscription.unsubscribe();
    }
    subscription = service.fetchData()
    .subscribe(...);
    }
    @Override
    public void onDestroy() {
    subscription.unsubscribe();
    super.onDestroy();
    }
    Awkward

    View full-size slide

  11. POTATOTIPS #29 (2016-05-25)
    2. REPLACE AN EXISTING SUBSCRIPTION
    private Subscription subscription = Susbscriptions.empty();
    // can be called multiple times
    private void update() {
    // cancel the previous request if necessary
    if (!subscription.isUnsubscribed()) {
    subscription.unsubscribe();
    }
    subscription = service.fetchData()
    .subscribe(...);
    }
    @Override
    public void onDestroy() {
    subscription.unsubscribe();
    super.onDestroy();
    }

    View full-size slide

  12. POTATOTIPS #29 (2016-05-25)
    2. REPLACE AN EXISTING SUBSCRIPTION
    private Subscription subscription =
    // can be called multiple times
    private void update() {
    // cancel the previous request if necessary
    if (!subscription.isUnsubscribed()) {
    subscription.unsubscribe();
    }
    subscription = service.fetchData()
    .subscribe(...);
    }
    @Override
    public void onDestroy() {
    subscription.unsubscribe();
    super.onDestroy();
    }

    View full-size slide

  13. POTATOTIPS #29 (2016-05-25)
    2. REPLACE AN EXISTING SUBSCRIPTION
    private SerialSubscription subscription = new SerialSubscription();
    // can be called multiple times
    private void update() {
    // cancel the previous request if necessary
    if (!subscription.isUnsubscribed()) {
    subscription.unsubscribe();
    }.
    subscription = service.fetchData()
    .subscribe(...);
    }
    @Override
    public void onDestroy() {
    subscription.unsubscribe();
    super.onDestroy();
    }

    View full-size slide

  14. POTATOTIPS #29 (2016-05-25)
    2. REPLACE AN EXISTING SUBSCRIPTION
    private SerialSubscription subscription = new SerialSubscription();
    // can be called multiple times
    private void update() {
    // cancel the previous request if necessary
    subscription = service.fetchData()
    .subscribe(...);
    }
    @Override
    public void onDestroy() {
    subscription.unsubscribe();
    super.onDestroy();
    }

    View full-size slide

  15. POTATOTIPS #29 (2016-05-25)
    2. REPLACE AN EXISTING SUBSCRIPTION
    private SerialSubscription subscription = new SerialSubscription();
    // can be called multiple times
    private void update() {
    // cancel the previous request if necessary
    subscription.set(service.fetchData()
    .subscribe(...));
    }
    @Override
    public void onDestroy() {
    subscription.unsubscribe();
    super.onDestroy();
    }

    View full-size slide

  16. POTATOTIPS #29 (2016-05-25)
    2. REPLACE AN EXISTING SUBSCRIPTION
    private SerialSubscription subscription = new SerialSubscription();
    // can be called multiple times
    private void update() {
    // cancel the previous request if necessary
    subscription.set(service.fetchData()
    .subscribe(...));
    }
    @Override
    public void onDestroy() {
    subscription.unsubscribe();
    super.onDestroy();
    }
    The previous subscription is automatically

    unsubscribed

    View full-size slide

  17. POTATOTIPS #29 (2016-05-25)
    3. APPLY A COMMON SET OF OPERATORS WITH COMPOSE()
    private void update() {
    // cancel the previous request if necessary
    subscription = service.fetchData()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(...);
    }
    Applying the same thread operators

    every time? Use compose()

    View full-size slide

  18. POTATOTIPS #29 (2016-05-25)
    3. APPLY A COMMON SET OF OPERATORS WITH COMPOSE()
    private void update() {
    // cancel the previous request if necessary
    subscription = service.fetchData()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(...);
    }

    View full-size slide

  19. POTATOTIPS #29 (2016-05-25)
    3. APPLY A COMMON SET OF OPERATORS WITH COMPOSE()
    private void update() {
    // cancel the previous request if necessary
    subscription = service.fetchData()
    .subscribe(...);
    }
    public static Observable.Transformer applySchedulers() {
    return new Observable.Transformer() {
    @Override
    public Observable call(Observable observable) {
    return observable
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread());
    }
    };
    }

    View full-size slide

  20. POTATOTIPS #29 (2016-05-25)
    3. APPLY A COMMON SET OF OPERATORS WITH COMPOSE()
    private void update() {
    // cancel the previous request if necessary
    subscription = service.fetchData()
    .compose(RxUtil.applySchedulers())
    .subscribe(...);
    }
    public static Observable.Transformer applySchedulers() {
    return new Observable.Transformer() {
    @Override
    public Observable call(Observable observable) {
    return observable
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread());
    }
    };
    }

    View full-size slide

  21. POTATOTIPS #29 (2016-05-25)
    4. AVOID A CUSTOM ONSUBSCRIBE
    public static Observable do() {
    return Observable.create(subscriber -> {
    try {
    subscriber.onNext(doSomething());
    subscriber.onCompleted();
    } catch (Exception e) {
    subscriber.onError(e);
    }
    });
    }
    ▸ Don’t create your OnSubscribe if possible
    ▸ It’s hard to implement properly

    Observable contract, Backpressure, Subscription handling

    View full-size slide

  22. POTATOTIPS #29 (2016-05-25)
    4. AVOID A CUSTOM ONSUBSCRIBE
    public static Observable do() {
    return Observable.create(subscriber -> {
    try {
    subscriber.onNext(doSomething());
    subscriber.onCompleted();
    } catch (Exception e) {
    subscriber.onError(e);
    }
    });
    }

    View full-size slide

  23. POTATOTIPS #29 (2016-05-25)
    4. AVOID A CUSTOM ONSUBSCRIBE
    public static Observable do() {
    return Observable. (subscriber -> {
    try {
    subscriber.onNext(doSomething());
    subscriber.onCompleted();
    } catch (Exception e) {
    subscriber.onError(e);
    }
    });
    }

    View full-size slide

  24. POTATOTIPS #29 (2016-05-25)
    4. AVOID A CUSTOM ONSUBSCRIBE
    public static Observable do() {
    return Observable.fromCallable(subscriber -> {
    try {
    subscriber.onNext(doSomething());
    subscriber.onCompleted();
    } catch (Exception e) {
    subscriber.onError(e);
    }
    });
    }

    View full-size slide

  25. POTATOTIPS #29 (2016-05-25)
    4. AVOID A CUSTOM ONSUBSCRIBE
    public static Observable do() {
    return Observable.fromCallable(() -> {
    try {
    subscriber.onNext(doSomething());
    subscriber.onCompleted();
    } catch (Exception e) {
    subscriber.onError(e);
    }
    });
    }

    View full-size slide

  26. POTATOTIPS #29 (2016-05-25)
    4. AVOID A CUSTOM ONSUBSCRIBE
    public static Observable do() {
    return Observable.fromCallable(() -> doSomething());
    }

    View full-size slide

  27. POTATOTIPS #29 (2016-05-25)
    4. AVOID A CUSTOM ONSUBSCRIBE
    public static Observable do() {
    return Observable.fromCallable(() -> doSomething());
    }
    ▸ Don’t create your OnSubscribe if possible
    ▸ Use Observable.fromCallable() instead

    View full-size slide

  28. POTATOTIPS #29 (2016-05-25)
    5. CONCAT().FIRST() FOR MULTIPLE RESOURCE ACCESS
    ▸ concat(observable1, observable2, …)
    ▸ Concatenates the events emit from the observables
    ▸ Take events from ovservable1
    ▸ On completed, take events from observable2
    ▸ And so on
    ▸ first(condition)
    ▸ Filters the events and returns the first event satisfying the condition
    ▸ concat().first()
    ▸ Access the observables one by one and returns the first valid resource

    View full-size slide

  29. POTATOTIPS #29 (2016-05-25)
    5. CONCAT().FIRST() FOR MULTIPLE RESOURCE ACCESS
    // Create our sequence for querying best available data
    Observable source = Observable.concat(
    sources.memory(),
    sources.disk(),
    sources.network()
    )
    .first(data -> data != null && data.isUpToDate());
    from https://github.com/dlew/rxjava-multiple-sources-sample
    ▸ Check memory/disk/network one by one and return the
    available data

    View full-size slide