rxjava_modules

 rxjava_modules

93bc8fb48f57c11e417dad9d26a2fb8a?s=128

petitviolet

January 13, 2016
Tweet

Transcript

  1. RxJava modules  potatotips #25 @petitviolet Fringe81 Co,. Ltd.

  2. About Me • Hiroki Komurasaki • @petitviolet • Fringe81 Co,.

    Ltd • Scala Engineer • ちょっと前までAndroid 
  3. RxJava 使ってますか? 

  4. https://github.com/ReactiveX 

  5. 

  6. RxJavaに色々と モジュールがあるので ちょっと触ってみた 

  7. RxJavaString https://github.com/ReactiveX/RxJavaString 

  8. private static void log(String msg) {
 Log.d(TAG, msg);
 } Observable<String>

    toSplit = Observable.just("a,b,c");
 StringObservable
 .split(toSplit, ",")
 .subscribe(RxString::log);
 
 Observable<String> toByLine = Observable.just("x\ny\nz\n");
 StringObservable
 .byLine(toByLine)
 .subscribe(RxString::log);
 // == StringObservable.split(toByLine, "\n") 
  9. private static void log(String msg) {
 Log.d(TAG, msg);
 } Observable<String>

    toJoin = Observable.just("x", "y", "z");
 StringObservable
 .join(toJoin, ":")
 .subscribe(RxString::log);
 
 Observable<String> toConcat = Observable.just("A", "B", "C");
 StringObservable
 .stringConcat(toConcat)
 .subscribe(RxString::log);
 // == StringObservable.join(toConcat, "") 
  10. 文字列に関する便利機能 • Observable<String>に対して文字列処理を簡単に 行えるようにするためのショートカット • InputStreamとかReaderも対象となる • encode/decodeもある 

  11. RxJavaMath https://github.com/ReactiveX/RxJavaMath 

  12. Observable<Integer> src = Observable.just(1, 2, 3, 4, 5);
 MathObservable
 .averageInteger(src)


    .subscribe(RxMath::log);
 
 MathObservable
 .min(src)
 .subscribe(RxMath::log);
 
 MathObservable
 .max(src)
 .subscribe(RxMath::log);
 
 MathObservable
 .sumInteger(src)
 .subscribe(RxMath::log); 
  13. static class User {
 private final String name;
 private final

    String email;
 
 User(String name, String email) {
 this.name = name;
 this.email = email;
 }
 
 @Override
 public String toString() {
 return "User(" + name + ", " + email + ")";
 }
 } Observable<User> users = Observable.just(
 new User("alice", "alice@aaa.com"),
 new User("bob", "bob-long-email@bbb.com"),
 new User("charley", "charley@ccc.com")
 );
 MathObservable
 .from(users)
 .averageInteger(u -> u.email.length())
 .subscribe(RxMath::log); // 5 MathObservable
 .from(users)
 .max((u1, u2) -> u1.email.length() - u2.email.length())
 .subscribe(RxMath::log); // User(bob, bob-long-email@bbb.com) 
  14. 数値に関する便利機能 • 平均・最大・最小を求めるためのショートカット • 独自のFunction1やComparatorを使える • fromでMathObservableに変換出来る 

  15. RxJavaDebug https://github.com/ReactiveX/RxJavaDebug 

  16. public static void debug(List<Integer> list) {
 SimpleDebugNotificationListener listener = new

    SimpleDebugNotificationListener();
 DebugHook<SimpleContext<?>> hook = new DebugHook<>(listener);
 
 RxJavaPlugins.getInstance().registerObservableExecutionHook(hook);
 
 Observable.from(list)
 .flatMap(i -> Observable.from(Arrays.asList(i, i * 100)))
 .subscribe(integer -> {
 Log.d(TAG, "integer -> " + integer);
 });
 
 SortedSet<NotificationsByObservable<?>> snapshot =
 listener.getNotificationsByObservable();
 
 Log.d(TAG, listener.toString(snapshot)); 
 } List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
 debug(list); 
  17. public static void debug(List<Integer> list) {
 SimpleDebugNotificationListener listener = new

    SimpleDebugNotificationListener();
 DebugHook<SimpleContext<?>> hook = new DebugHook<>(listener);
 
 RxJavaPlugins.getInstance().registerObservableExecutionHook(hook);
 
 Observable.from(list)
 .flatMap(i -> Observable.from(Arrays.asList(i, i * 100)))
 .subscribe(integer -> {
 Log.d(TAG, "integer -> " + integer);
 });
 
 SortedSet<NotificationsByObservable<?>> snapshot =
 listener.getNotificationsByObservable();
 
 Log.d(TAG, listener.toString(snapshot)); 
 } List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
 debug(list); 
  18. public static void debug(List<Integer> list) {
 SimpleDebugNotificationListener listener = new

    SimpleDebugNotificationListener();
 DebugHook<SimpleContext<?>> hook = new DebugHook<>(listener);
 
 RxJavaPlugins.getInstance().registerObservableExecutionHook(hook);
 
 Observable.from(list)
 .flatMap(i -> Observable.from(Arrays.asList(i, i * 100)))
 .subscribe(integer -> {
 Log.d(TAG, "integer -> " + integer);
 });
 
 SortedSet<NotificationsByObservable<?>> snapshot =
 listener.getNotificationsByObservable();
 
 Log.d(TAG, listener.toString(snapshot)); 
 } List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
 debug(list); 
  19. public static void debug(List<Integer> list) {
 SimpleDebugNotificationListener listener = new

    SimpleDebugNotificationListener();
 DebugHook<SimpleContext<?>> hook = new DebugHook<>(listener);
 
 RxJavaPlugins.getInstance().registerObservableExecutionHook(hook);
 
 Observable.from(list)
 .flatMap(i -> Observable.from(Arrays.asList(i, i * 100)))
 .subscribe(integer -> {
 Log.d(TAG, "integer -> " + integer);
 });
 
 SortedSet<NotificationsByObservable<?>> snapshot =
 listener.getNotificationsByObservable();
 
 Log.d(TAG, listener.toString(snapshot)); 
 } List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
 debug(list); 
  20.  integer -> 1 integer -> 100 integer -> 2

    integer -> 200 integer -> 3 integer -> 300 integer -> 4 integer -> 400 integer -> 5 integer -> 500 { "rx.Observable$27@225cfc95": [ {"ns_duration": 17179472, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "Subscribe", "source": "rx.Observable@18c8287c", "sourceFunc": "rx.Observable$2@15773505"}}, {"ns_duration": 127946, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "Request", "n": 9223372036854775807, "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 190474, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "1", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 51643, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "100", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 60648, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "2", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 31561, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "200", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 47015, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "3", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 51790, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "300", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 451663, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "4", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 404011, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "400", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 41103, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "5", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 72118, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "500", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 33840, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnCompleted", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 3058, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "Unsubscribe", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}} ], "rx.internal.operators.OperatorMerge$MergeSubscriber@26cb21aa": [ {"ns_duration": 7064, "threadId": 1, "notification": {"observer": "rx.internal.operators.OperatorMerge$MergeSubscriber@26cb21aa", "type": "OnStart", "to": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 16027011, "threadId": 1, "notification": {"observer": "rx.internal.operators.OperatorMerge$MergeSubscriber@26cb21aa", "type": "Request", "n": 9223372036854775807, "from": "rx.internal.operators.OperatorMap@2ecfd78b", "to": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 13054812, "threadId": 1, "notification": {"observer": "rx.internal.operators.OperatorMerge$MergeSubscriber@26cb21aa", "type": "OnNext", "value": "rx.Observable@2ad5068", "from": "rx.internal.operators.OperatorMap@2ecfd78b", "to": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 21963, "threadId": 1, "notification": {"observer": "rx.internal.operators.OperatorMerge$MergeSubscriber@26cb21aa", "type": "Request", "n": 1, "from": "rx.internal.operators.OperatorMap@2ecfd78b", "to": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 406769, "threadId": 1, "notification": {"observer": "rx.intern /(^o^)\
  21.  integer -> 1 integer -> 100 integer -> 2

    integer -> 200 integer -> 3 integer -> 300 integer -> 4 integer -> 400 integer -> 5 integer -> 500 subscribeしたところ Observable.from(list)
 .flatMap(i -> Observable.from(Arrays.asList(i, i * 100)))
 .subscribe(integer -> {
 Log.d(TAG, "integer -> " + integer);
 });
  22.  { "rx.Observable$27@225cfc95": [ {"ns_duration": 17179472, "threadId": 1, "notification": {"observer":

    "rx.Observable$27@225cfc95", "type": "Subscribe", "source": "rx.Observable@18c8287c", "sourceFunc": "rx.Observable$2@15773505"}}, {"ns_duration": 127946, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "Request", "n": 9223372036854775807, "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 190474, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "1", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 51643, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "100", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 60648, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "2", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 31561, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "200", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 47015, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "3", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 51790, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "300", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 451663, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "4", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 404011, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "400", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 41103, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "5", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 72118, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "500", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 33840, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "OnCompleted", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}}, {"ns_duration": 3058, "threadId": 1, "notification": {"observer": "rx.Observable$27@225cfc95", "type": "Unsubscribe", "from": "rx.internal.operators.OperatorMerge@3cc7495a"}} ], DebugHookによって出されるログ
  23.  {"ns_duration": 17179472, "threadId": 1, "notification": { "observer": “rx.Observable$27@225cfc95", "type":

    "Subscribe", "source": "rx.Observable@18c8287c", "sourceFunc": “rx.Observable$2@15773505" } }, 一部抽出・拡大 {"ns_duration": 190474, "threadId": 1, "notification": { "observer": "rx.Observable$27@225cfc95", "type": "OnNext", "value": "1", "from": “rx.internal.operators.OperatorMerge@3cc7495a" } },
  24. いろいろ情報が見れて便利 • Observerに対する以下が分かる • どのスレッドで • どのObservableの • どのonXXXから •

    どんな値が渡ってきているか • 注意点としてはObservableを作る前に設定を行うこと 
  25. RxJavaJoins https://github.com/ReactiveX/RxJavaJoins 

  26. Observable<Integer> src_i = Observable.just(1, 2, 3, 4, 5);
 Observable<String> src_s

    = Observable.just("a", "b", "c");
 Observable<Long> interval = Observable.interval(1, SECONDS);
 
 Plan0<String> plan =
 JoinObservable
 .from(src_i)
 .and(src_s)
 .and(interval)
 .then((i, s, l) -> i + ", " + s + ", " + l); 
 JoinObservable
 .when(plan)
 .toObservable()
 .subscribe(RxJoin::log); // 1, a, 0 // 2, b, 1 // 3, c, 2 
  27. Observable<Integer> src_i = Observable.just(1, 2, 3, 4, 5);
 Observable<String> src_s

    = Observable.just("a", "b", "c");
 Observable<Long> interval = Observable.interval(1, SECONDS);
 
 Observable.zip(
 src_i, src_s, interval,
 (i, s, l) -> i + ", " + s + ", " + l)
 .subscribe(RxJoin::log); // 1, a, 0 // 2, b, 1 // 3, c, 2  zip使っても書ける
  28. Observableをまとめるやつ • zipでいいのでは • 違いがわからず • 流れるようなinterfaceで書けるのが利点? • and, then,

    when 
  29. まとめ • RxJavaはモジュール化されている • 特定の機能を持つモジュール群が存在 • 用途にあったものが実装されているかも • 今回紹介しなかったのも多数 •

    AsyncUtilとかParallelなんかも見えた