$30 off During Our Annual Pro Sale. View Details »

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
  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
  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
  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(); }
  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
  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(); }
  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(); }
  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(); }
  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(); }
  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
  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(); }
  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(); }
  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(); }
  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(); }
  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(); }
  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
  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()
  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(...); }
  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 <T> Observable.Transformer<T, T> applySchedulers() { return new Observable.Transformer<T, T>() { @Override public Observable<T> call(Observable<T> observable) { return observable .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } }; }
  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.<Data>applySchedulers()) .subscribe(...); } public static <T> Observable.Transformer<T, T> applySchedulers() { return new Observable.Transformer<T, T>() { @Override public Observable<T> call(Observable<T> observable) { return observable .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } }; }
  21. POTATOTIPS #29 (2016-05-25) 4. AVOID A CUSTOM ONSUBSCRIBE public static

    Observable<Result> 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
  22. POTATOTIPS #29 (2016-05-25) 4. AVOID A CUSTOM ONSUBSCRIBE public static

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

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

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

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

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

    Observable<Result> do() { return Observable.fromCallable(() -> doSomething()); } ▸ Don’t create your OnSubscribe if possible ▸ Use Observable.fromCallable() instead
  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
  29. POTATOTIPS #29 (2016-05-25) 5. CONCAT().FIRST() FOR MULTIPLE RESOURCE ACCESS //

    Create our sequence for querying best available data Observable<Data> 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