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

rxjava_modules

petitviolet
January 13, 2016

 rxjava_modules

petitviolet

January 13, 2016
Tweet

More Decks by petitviolet

Other Decks in Programming

Transcript

  1. RxJava
    modules

    potatotips #25
    @petitviolet
    Fringe81 Co,. Ltd.

    View Slide

  2. About Me
    • Hiroki Komurasaki
    • @petitviolet
    • Fringe81 Co,. Ltd
    • Scala Engineer
    • ちょっと前までAndroid

    View Slide

  3. RxJava
    使ってますか?

    View Slide

  4. https://github.com/ReactiveX

    View Slide


  5. View Slide

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

    View Slide

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

    View Slide

  8. private static void log(String msg) {

    Log.d(TAG, msg);

    }
    Observable toSplit = Observable.just("a,b,c");

    StringObservable

    .split(toSplit, ",")

    .subscribe(RxString::log);


    Observable toByLine = Observable.just("x\ny\nz\n");

    StringObservable

    .byLine(toByLine)

    .subscribe(RxString::log);

    // == StringObservable.split(toByLine, "\n")

    View Slide

  9. private static void log(String msg) {

    Log.d(TAG, msg);

    }
    Observable toJoin = Observable.just("x", "y", "z");

    StringObservable

    .join(toJoin, ":")

    .subscribe(RxString::log);


    Observable toConcat = Observable.just("A", "B", "C");

    StringObservable

    .stringConcat(toConcat)

    .subscribe(RxString::log);

    // == StringObservable.join(toConcat, "")

    View Slide

  10. 文字列に関する便利機能
    • Observableに対して文字列処理を簡単に
    行えるようにするためのショートカット
    • InputStreamとかReaderも対象となる
    • encode/decodeもある

    View Slide

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

    View Slide

  12. Observable 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);

    View Slide

  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 users = Observable.just(

    new User("alice", "[email protected]"),

    new User("bob", "[email protected]"),

    new User("charley", "[email protected]")

    );

    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, [email protected])

    View Slide

  14. 数値に関する便利機能
    • 平均・最大・最小を求めるためのショートカット
    • 独自のFunction1やComparatorを使える
    • fromでMathObservableに変換出来る

    View Slide

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

    View Slide

  16. public static void debug(List list) {

    SimpleDebugNotificationListener listener = new SimpleDebugNotificationListener();

    DebugHook> 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> snapshot =

    listener.getNotificationsByObservable();


    Log.d(TAG, listener.toString(snapshot)); 

    }
    List list = Arrays.asList(1, 2, 3, 4, 5);

    debug(list);

    View Slide

  17. public static void debug(List list) {

    SimpleDebugNotificationListener listener = new SimpleDebugNotificationListener();

    DebugHook> 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> snapshot =

    listener.getNotificationsByObservable();


    Log.d(TAG, listener.toString(snapshot)); 

    }
    List list = Arrays.asList(1, 2, 3, 4, 5);

    debug(list);

    View Slide

  18. public static void debug(List list) {

    SimpleDebugNotificationListener listener = new SimpleDebugNotificationListener();

    DebugHook> 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> snapshot =

    listener.getNotificationsByObservable();


    Log.d(TAG, listener.toString(snapshot)); 

    }
    List list = Arrays.asList(1, 2, 3, 4, 5);

    debug(list);

    View Slide

  19. public static void debug(List list) {

    SimpleDebugNotificationListener listener = new SimpleDebugNotificationListener();

    DebugHook> 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> snapshot =

    listener.getNotificationsByObservable();


    Log.d(TAG, listener.toString(snapshot)); 

    }
    List list = Arrays.asList(1, 2, 3, 4, 5);

    debug(list);

    View Slide


  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^)\

    View Slide


  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);

    });

    View Slide


  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によって出されるログ

    View Slide


  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"
    }
    },

    View Slide

  24. いろいろ情報が見れて便利
    • Observerに対する以下が分かる
    • どのスレッドで
    • どのObservableの
    • どのonXXXから
    • どんな値が渡ってきているか
    • 注意点としてはObservableを作る前に設定を行うこと

    View Slide

  25. RxJavaJoins
    https://github.com/ReactiveX/RxJavaJoins

    View Slide

  26. Observable src_i = Observable.just(1, 2, 3, 4, 5);

    Observable src_s = Observable.just("a", "b", "c");

    Observable interval = Observable.interval(1, SECONDS);


    Plan0 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

    View Slide

  27. Observable src_i = Observable.just(1, 2, 3, 4, 5);

    Observable src_s = Observable.just("a", "b", "c");

    Observable 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使っても書ける

    View Slide

  28. Observableをまとめるやつ
    • zipでいいのでは
    • 違いがわからず
    • 流れるようなinterfaceで書けるのが利点?
    • and, then, when

    View Slide

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

    View Slide