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

初心者のための RxJava

初心者のための RxJava

本セッションでは、最近 Android アプリ開発で注目を浴びている Reactive Extension (Rx) と呼ばれる非同期処理を扱うライブラリについて簡単に説明し、さらに RxJava を例に、それをどのように実際の開発に活用していくかを解説します。

Rx はその考え方を理解するまでに時間がかかること、オペレータやコンセプトが多すぎて、どのように適切に使えば良いか分からないことから、学習コストが高いと言われています。本セッションでは、そのような Rx 初心者のために、Rx のコアとなる概念と併せて具体的な利用方法や効果的な学習法について説明いたします。

参考:
- Reactive programming - Wikipedia, the free encyclopedia
https://en.wikipedia.org/wiki/Reactive_programming

- JJUG ナイトセミナーで Reactive Streams について発表しました

http://okapies.hateblo.jp/entry/2015/06/26/024505

- ReactiveX
http://reactivex.io/

- Exploring RxJava 2 for Android (GOTOcph October 2016)

https://speakerdeck.com/jakewharton/exploring-rxjava-2-for-android-gotocph-october-2016

- Reactive Programming with JDK 9 Flow API
https://community.oracle.com/docs/DOC-1006738

Hiroshi Kurokawa

October 09, 2016
Tweet

More Decks by Hiroshi Kurokawa

Other Decks in Technology

Transcript

  1. ⴱ䗰罏ך׋׭ך
    3Y+BWB
    랲䊛峔 吳䒭⠓爡'BCMJD

    !IZESBLFDBU

    View full-size slide

  2. 3Y+BWB
    ˖ 3Y 3FBDUJWF&YUFOTJPO
    ך+BWB㹋鄲

    View full-size slide

  3. 3Y+BWB
    ˖ 3Y 3FBDUJWF&YUFOTJPO
    ך+BWB㹋鄲
    3FBDUJWF

    View full-size slide

  4. 3FBDUJWF1SPHSBNNJOHהכ
    ˑBQSPHSBNNJOHQBSBEJHNPSJFOUFEBSPVOEEBUBGMPXTBOEUIF
    QSPQBHBUJPOPGDIBOHF˒
    3FBDUJWFQSPHSBNNJOH8JLJQFEJB IUUQTFOXJLJQFEJBPSHX
    JOEFYQIQ UJUMF3FBDUJWF@QSPHSBNNJOHPMEJE

    ˑ3FBDUJWFQSPHSBNTBMTPNBJOUBJOBDPOUJOVPVTJOUFSBDUJPOXJUI
    UIFJSFOWJSPONFOU CVUBUBTQFFEXIJDIJTEFUFSNJOFECZUIF
    FOWJSPONFOU OPUUIFQSPHSBNJUTFMG˒
    3FBDUJWFQSPHSBNNJOH8JLJQFEJB IUUQTFOXJLJQFEJBPSHXJLJ3FBDUJWF@QSPHSBNNJOH

    View full-size slide

  5. 3FBDUJWF1SPHSBNNJOHהכ
    ˑ3FBDUJWFQSPHSBNTBMTPNBJOUBJOBDPOUJOVPVTJOUFSBDUJPOXJUI
    UIFJSFOWJSPONFOU CVUBUBTQFFEXIJDIJTEFUFSNJOFECZUIF
    FOWJSPONFOU OPUUIFQSPHSBNJUTFMG˒
    3FBDUJWFQSPHSBNNJOH8JLJQFEJB IUUQTFOXJLJQFEJBPSHXJLJ3FBDUJWF@QSPHSBNNJOH

    ˑBQSPHSBNNJOHQBSBEJHNPSJFOUFEBSPVOEEBUBGMPXTBOEUIF
    QSPQBHBUJPOPGDIBOHF˒
    3FBDUJWFQSPHSBNNJOH8JLJQFEJB IUUQTFOXJLJQFEJBPSHX
    JOEFYQIQ UJUMF3FBDUJWF@QSPHSBNNJOHPMEJE

    View full-size slide

  6. 3FBDUJWF1SPHSBNNJOHהכ
    ˑBQSPHSBNNJOHQBSBEJHNPSJFOUFEBSPVOEEBUBGMPXTBOEUIF
    QSPQBHBUJPOPGDIBOHF˒
    3FBDUJWFQSPHSBNNJOH8JLJQFEJB IUUQTFOXJLJQFEJBPSHXJLJ3FBDUJWF@QSPHSBNNJOH

    5SBOTGPSNBUJPOBM 㢌䳔㘗
    㢌侧ח㼎ׅ׷乼⡲׾אא鎸鶢

    View full-size slide

  7. 3FBDUJWF1SPHSBNNJOHהכ
    ˑBQSPHSBNNJOHQBSBEJHNPSJFOUFEBSPVOEEBUBGMPXTBOEUIF
    QSPQBHBUJPOPGDIBOHF˒
    3FBDUJWFQSPHSBNNJOH8JLJQFEJB IUUQTFOXJLJQFEJBPSHXJLJ3FBDUJWF@QSPHSBNNJOH

    5SBOTGPSNBUJPOBM 㢌䳔㘗
    㢌侧ח㼎ׅ׷乼⡲׾אא鎸鶢
    3FBDUJWF
    ر٦ةؿٗ٦׾㹑鎉׃גַ׵ծ㢌刿׾⠗乄ׇׁ׷

    View full-size slide

  8. 5SBOTGPSNBUJPOBM
    3FBDUJWF1SPHSBNNJOHהכ
    A = 2
    B = 3
    C = (A + 1) x (B - 1)

    View full-size slide

  9. 3FBDUJWF1SPHSBNNJOHהכ
    A = 2
    B = 3
    C = (A + 1) x (B - 1)
    3FBDUJWF


    Y
    "
    #
    $
    5SBOTGPSNBUJPOBM

    View full-size slide

  10. 3FBDUJWF1SPHSBNNJOHהכ
    A = 2
    B = 3
    C = (A + 1) x (B - 1)


    Y
    "
    #
    $


    5SBOTGPSNBUJPOBM 3FBDUJWF

    View full-size slide

  11. 3FBDUJWF1SPHSBNNJOHהכ
    A = 2
    B = 3
    C = (A + 1) x (B - 1)


    Y
    "
    #
    $



    5SBOTGPSNBUJPOBM 3FBDUJWF

    View full-size slide

  12. 3FBDUJWF1SPHSBNNJOHהכ
    A = 2
    B = 3
    C = (A + 1) x (B - 1)
    A = 3


    Y
    "
    #
    $



    5SBOTGPSNBUJPOBM 3FBDUJWF

    View full-size slide

  13. 3FBDUJWF1SPHSBNNJOHהכ
    A = 2
    B = 3
    C = (A + 1) x (B - 1)
    A = 3


    Y
    "
    #
    $



    5SBOTGPSNBUJPOBM 3FBDUJWF

    View full-size slide

  14. 3FBDUJWF1SPHSBNNJOHהכ
    A = 2
    B = 3
    C = (A + 1) x (B - 1)
    A = 3


    Y
    "
    #
    $



    5SBOTGPSNBUJPOBM 3FBDUJWF

    View full-size slide

  15. ז׈"OESPJE،فٔꟚ涪ד31ָ岣湡ׁ׸׷ךַ
    network.getDataA();

    View full-size slide

  16. ז׈"OESPJE،فٔꟚ涪ד31ָ岣湡ׁ׸׷ךַ
    network.getDataA(new NetworkCall.Listener() {

    @Override public void success(String data) {

    }

    });

    View full-size slide

  17. ז׈"OESPJE،فٔꟚ涪ד31ָ岣湡ׁ׸׷ךַ
    network.getDataA(new NetworkCall.Listener() {

    @Override public void success(String data) {

    network.getDataB(data);

    }

    });

    View full-size slide

  18. ז׈"OESPJE،فٔꟚ涪ד31ָ岣湡ׁ׸׷ךַ
    network.getDataA(new NetworkCall.Listener() {

    @Override public void success(String data) {

    network.getDataB(data, new NetworkCall.Listener() {

    @Override public void success(String data) {

    }‌

    });

    }

    });

    View full-size slide

  19. ז׈"OESPJE،فٔꟚ涪ד31ָ岣湡ׁ׸׷ךַ
    network.getDataA(new NetworkCall.Listener() {

    @Override public void success(String data) {

    network.getDataB(data, new NetworkCall.Listener() {

    @Override public void success(String data) {

    tv.setText(data);

    }‌

    });

    }

    });

    View full-size slide

  20. ז׈"OESPJE،فٔꟚ涪ד31ָ岣湡ׁ׸׷ךַ
    network.getDataA(new NetworkCall.Listener() {

    @Override public void success(String data) {

    network.getDataB(data, new NetworkCall.Listener() {

    @Override public void success(String data) {

    tv.setText(data);

    }‌


    @Override public void failure(Throwable t) {}

    });

    }


    @Override public void failure(Throwable t) {}

    });

    View full-size slide

  21. ז׈"OESPJE،فٔꟚ涪ד31ָ岣湡ׁ׸׷ךַ
    network.getDataA(new NetworkCall.Listener() {

    @Override public void success(String data) {

    network.getDataB(data, new NetworkCall.Listener() {

    @Override public void success(String data) {

    if (!isDestroyed()) {

    tv.setText(data);

    }

    }‌


    @Override public void failure(Throwable t) {}

    });

    }


    @Override public void failure(Throwable t) {}

    });

    View full-size slide

  22. ז׈"OESPJE،فٔꟚ涪ד31ָ岣湡ׁ׸׷ךַ
    network.getDataA(new NetworkCall.Listener() {

    @Override public void success(String data) {

    network.getDataB(data, new NetworkCall.Listener() {

    @Override public void success(String data) {

    runOnUiThread(() -> {

    if (!isDestroyed()) {

    tv.setText(data);

    }

    });

    }‌


    @Override public void failure(Throwable t) {}

    });

    }


    @Override public void failure(Throwable t) {}

    });

    View full-size slide

  23. ז׈"OESPJE،فٔꟚ涪ד31ָ岣湡ׁ׸׷ךַ

    View full-size slide

  24. ז׈"OESPJE،فٔꟚ涪ד31ָ岣湡ׁ׸׷ךַ

    View full-size slide

  25. ז׈"OESPJE،فٔꟚ涪ד31ָ岣湡ׁ׸׷ךַ

    View full-size slide

  26. ז׈"OESPJE،فٔꟚ涪ד31ָ岣湡ׁ׸׷ךַ

    View full-size slide

  27. ז׈"OESPJE،فٔꟚ涪ד31ָ岣湡ׁ׸׷ךַ

    View full-size slide

  28. ז׈"OESPJE،فٔꟚ涪ד31ָ岣湡ׁ׸׷ךַ

    View full-size slide

  29. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    BMJCSBSZGPSDPNQPTJOHBTZODISPOPVTBOEFWFOUCBTFE
    QSPHSBNTVTJOHPCTFSWBCMFTFRVFODFT˒
    3FBDUJWF9*OUSP IUUQSFBDUJWFYJPJOUSPIUNM

    View full-size slide

  30. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    BMJCSBSZGPSDPNQPTJOHBTZODISPOPVTBOEFWFOUCBTFE
    QSPHSBNTVTJOHPCTFSWBCMFTFRVFODFT˒
    3FBDUJWF9*OUSP IUUQSFBDUJWFYJPJOUSPIUNM

    View full-size slide

  31. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    BMJCSBSZGPSDPNQPTJOHBTZODISPOPVTBOEFWFOUCBTFE
    QSPHSBNTVTJOHPCTFSWBCMFTFRVFODFT˒
    3FBDUJWF9*OUSP IUUQSFBDUJWFYJPJOUSPIUNM

    View full-size slide

  32. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    BMJCSBSZGPSDPNQPTJOHBTZODISPOPVTBOEFWFOUCBTFE
    QSPHSBNTVTJOHPCTFSWBCMFTFRVFODFT˒
    3FBDUJWF9*OUSP IUUQSFBDUJWFYJPJOUSPIUNM

    View full-size slide

  33. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    BMJCSBSZGPSDPNQPTJOHBTZODISPOPVTBOEFWFOUCBTFE
    QSPHSBNTVTJOHPCTFSWBCMFTFRVFODFT˒
    3FBDUJWF9*OUSP IUUQSFBDUJWFYJPJOUSPIUNM

    subscribe

    View full-size slide

  34. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    BMJCSBSZGPSDPNQPTJOHBTZODISPOPVTBOEFWFOUCBTFE
    QSPHSBNTVTJOHPCTFSWBCMFTFRVFODFT˒
    3FBDUJWF9*OUSP IUUQSFBDUJWFYJPJOUSPIUNM

    View full-size slide

  35. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    BMJCSBSZGPSDPNQPTJOHBTZODISPOPVTBOEFWFOUCBTFE
    QSPHSBNTVTJOHPCTFSWBCMFTFRVFODFT˒
    3FBDUJWF9*OUSP IUUQSFBDUJWFYJPJOUSPIUNM

    View full-size slide

  36. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    BMJCSBSZGPSDPNQPTJOHBTZODISPOPVTBOEFWFOUCBTFE
    QSPHSBNTVTJOHPCTFSWBCMFTFRVFODFT˒
    3FBDUJWF9*OUSP IUUQSFBDUJWFYJPJOUSPIUNM

    View full-size slide

  37. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    BMJCSBSZGPSDPNQPTJOHBTZODISPOPVTBOEFWFOUCBTFE
    QSPHSBNTVTJOHPCTFSWBCMFTFRVFODFT˒
    3FBDUJWF9*OUSP IUUQSFBDUJWFYJPJOUSPIUNM

    completed

    View full-size slide

  38. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    BMJCSBSZGPSDPNQPTJOHBTZODISPOPVTBOEFWFOUCBTFE
    QSPHSBNTVTJOHPCTFSWBCMFTFRVFODFT˒
    3FBDUJWF9*OUSP IUUQSFBDUJWFYJPJOUSPIUNM

    View full-size slide

  39. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    BMJCSBSZGPSDPNQPTJOHBTZODISPOPVTBOEFWFOUCBTFE
    QSPHSBNTVTJOHPCTFSWBCMFTFRVFODFT˒
    3FBDUJWF9*OUSP IUUQSFBDUJWFYJPJOUSPIUNM

    Observable
    subscribe(Subscriber)

    View full-size slide

  40. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    BMJCSBSZGPSDPNQPTJOHBTZODISPOPVTBOEFWFOUCBTFE
    QSPHSBNTVTJOHPCTFSWBCMFTFRVFODFT˒
    3FBDUJWF9*OUSP IUUQSFBDUJWFYJPJOUSPIUNM

    Observable
    subscribe(Subscriber)
    Subscriber
    onNext()
    onCompleted()
    onError()

    View full-size slide

  41. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    BMJCSBSZGPSDPNQPTJOHBTZODISPOPVTBOEFWFOUCBTFE
    QSPHSBNTVTJOHPCTFSWBCMFTFRVFODFT˒
    3FBDUJWF9*OUSP IUUQSFBDUJWFYJPJOUSPIUNM

    View full-size slide

  42. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    BMJCSBSZGPSDPNQPTJOHBTZODISPOPVTBOEFWFOUCBTFE
    QSPHSBNTVTJOHPCTFSWBCMFTFRVFODFT˒
    3FBDUJWF9*OUSP IUUQSFBDUJWFYJPJOUSPIUNM

    View full-size slide

  43. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    BMJCSBSZGPSDPNQPTJOHBTZODISPOPVTBOEFWFOUCBTFE
    QSPHSBNTVTJOHPCTFSWBCMFTFRVFODFT˒
    3FBDUJWF9*OUSP IUUQSFBDUJWFYJPJOUSPIUNM

    View full-size slide

  44. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    BMJCSBSZGPSDPNQPTJOHBTZODISPOPVTBOEFWFOUCBTFE
    QSPHSBNTVTJOHPCTFSWBCMFTFRVFODFT˒
    3FBDUJWF9*OUSP IUUQSFBDUJWFYJPJOUSPIUNM

    Operator

    View full-size slide

  45. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    1 2 3 4 5 6
    < >
    GPSxJO
    JGx % 2 == 0UIFO
    QVTIx * x UP list
    FOE
    FOE
    SFUVSOlist

    View full-size slide

  46. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    1 2 3 4 5 6
    < >
    GJMUFS x % 2 == 0

    NBQ x -> x * x

    View full-size slide

  47. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    1 2 3 4 5 6

    View full-size slide

  48. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    1 2 3 4 5 6
    GJMUFS x % 2 == 0

    NBQ x -> x * x

    View full-size slide

  49. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    1 2 3 4 5 6
    GJMUFS x % 2 == 0

    NBQ x -> x * x

    4 16 36

    View full-size slide

  50. 3FBDUJWF&YUFOTJPO 3Y
    הכ
    4
    16
    36
    Observable.just(1, 2, 3, 4, 5, 6)

    .filter(x -> x % 2 == 0)

    .map(x -> x * x)

    .subscribe(System.out ::println);

    View full-size slide

  51. ˖ ꬊず劍Ⳣ椚
    ˖ 6*؎كٝزⳢ椚
    ˖ ꬊず劍Ⳣ椚6*؎كٝزⳢ椚
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  52. ˖ ꬊず劍Ⳣ椚
    ˖ 6*؎كٝزⳢ椚
    ˖ ꬊず劍Ⳣ椚6*؎كٝزⳢ椚
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  53. 3Y+BWBד⡦ָדֹ׷ךַ
    network.getDataA(new NetworkCall.Listener() {

    @Override public void success(String data) {

    network.getDataB(data, new NetworkCall.Listener() {

    @Override public void success(String data) {

    runOnUiThread(() -> {

    if (!isDestroyed()) {

    tv.setText(data);

    }

    });

    }


    @Override public void failure(Throwable t) {}

    });

    }


    @Override public void failure(Throwable t) {}

    });

    View full-size slide

  54. network.getDataA();
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  55. network.getDataA()

    .subscribe(

    data -> tv.setText(data),

    throwable -> Log.e(TAG, throwable.getMessage())

    );
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  56. network.getDataA()

    .flatMap(data -> network.getDataB(data))

    .subscribe(

    data -> tv.setText(data),

    throwable -> Log.e(TAG, throwable.getMessage())

    );
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  57. network.getDataA()
    .subscribeOn(Schedulers.io())

    .flatMap(data -> network.getDataB(data))

    .subscribe(

    data -> tv.setText(data),

    throwable -> Log.e(TAG, throwable.getMessage())

    );
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  58. network.getDataA()
    .subscribeOn(Schedulers.io())

    .flatMap(data -> network.getDataB(data))
    .observeOn(AndroidSchedulers.mainThread())

    .subscribe(

    data -> tv.setText(data),

    throwable -> Log.e(TAG, throwable.getMessage())

    );
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  59. subscription = network.getDataA()

    .subscribeOn(Schedulers.io())

    .flatMap(data -> network.getDataB(data))
    .observeOn(AndroidSchedulers.mainThread())

    .subscribe(

    data -> tv.setText(data),

    throwable -> Log.e(TAG, throwable.getMessage())

    );
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  60. @Override public void onCreate(Bundle savedInstanceState) {
    …

    subscription = network.getDataA()

    .subscribeOn(Schedulers.io())

    .flatMap(data -> network.getDataB(data))

    .observeOn(AndroidSchedulers.mainThread())

    .subscribe(

    data -> tv.setText(data),

    throwable -> Log.e(TAG, throwable.getMessage())

    );

    }
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  61. @Override public void onCreate(Bundle savedInstanceState) {
    …

    subscription = network.getDataA()

    .subscribeOn(Schedulers.io())

    .flatMap(data -> network.getDataB(data))

    .observeOn(AndroidSchedulers.mainThread())

    .subscribe(

    data -> tv.setText(data),

    throwable -> Log.e(TAG, throwable.getMessage())

    );

    }

    @Override public void onDestroy() {

    super.onDestroy();

    subscription.unsubscribe();

    }
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  62. @Override public void onCreate(Bundle savedInstanceState) {
    …

    subscription = network.getDataA()

    .subscribeOn(Schedulers.io())

    .flatMap(data -> network.getDataB(data))

    .observeOn(AndroidSchedulers.mainThread())

    .subscribe(

    data -> tv.setText(data),

    throwable -> Log.e(TAG, throwable.getMessage())

    );

    }

    @Override public void onDestroy() {

    super.onDestroy();

    subscription.unsubscribe();

    }
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  63. 3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  64. ˖ ꬊず劍Ⳣ椚
    ˖ 6*؎كٝزⳢ椚
    ˖ ꬊず劍Ⳣ椚6*؎كٝزⳢ椚
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  65. 6*؎كٝزⳢ椚
    ׅץגWBMJE׌׏׋㜥さך׫
    TVCNJUنةٝ׾FOBCMFחׅ׷
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  66. 8JUIPVU3Y+BWB
    private void setup() {

    input1.addTextChangedListener(new TextWatcher() {

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    input1Valid = s.length() > 0;

    validate();

    }

    });


    }


    private void validate() {

    button.setEnabled(input1Valid && input2Valid && input3Valid);

    }
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  67. 8JUI3Y+BWB
    private void setup() {

    ArrayList> validators = new ArrayList <>();

    validators.add(RxTextView.textChanges(input1).map(s -> s.length() > 0));



    Observable.combineLatest(validators, args -> {

    for (Object a : args) {

    if (!(Boolean) a) return false;

    }

    return true;

    }).subscribe(button ::setEnabled);

    }
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  68. 8JUI3Y+BWB
    private void setup() {

    ArrayList> validators = new ArrayList <>();

    validators.add(RxTextView.textChanges(input1).map(s -> s.length() > 0));



    Observable.combineLatest(validators, args -> {

    for (Object a : args) {

    if (!(Boolean) a) return false;

    }

    return true;

    }).subscribe(button ::setEnabled);

    }
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  69. 8JUI3Y+BWB
    private void setup() {

    ArrayList> validators = new ArrayList <>();

    validators.add(RxTextView.textChanges(input1).map(s -> s.length() > 0));



    Observable.combineLatest(validators, args -> {

    for (Object a : args) {

    if (!(Boolean) a) return false;

    }

    return true;

    }).subscribe(button ::setEnabled);

    }
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  70. 8JUI3Y+BWB
    private void setup() {

    ArrayList> validators = new ArrayList <>();

    validators.add(RxTextView.textChanges(input1).map(s -> s.length() > 0));



    Observable.combineLatest(validators, args -> {

    for (Object a : args) {

    if (!(Boolean) a) return false;

    }

    return true;

    }).subscribe(button ::setEnabled);

    }
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  71. 3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  72. ˖ ꬊず劍Ⳣ椚
    ˖ 6*؎كٝزⳢ椚
    ˖ ꬊず劍Ⳣ椚6*؎كٝزⳢ椚
    3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  73. 3Y+BWBד⡦ָדֹ׷ךַ
    ꬊず劍Ⳣ椚6*؎كٝزⳢ椚
    ꬊず劍Ⳣ椚6*؎كٝزⳢ椚

    View full-size slide

  74. 3Y+BWBד⡦ָדֹ׷ךַ
    ꬊず劍Ⳣ椚6*؎كٝزⳢ椚
    أؙٗ٦ָٕ⨡姺׃׋׵ꬊず
    劍Ⳣ椚׾㨣׭ծأؙٗ٦ָٕ
    Ꟛ㨣׃׋׵װ׭׷
    ؕؐٝزָחז׏׋׵
    穠卓ָ邌爙ׁ׸׷

    View full-size slide

  75. 3Y+BWBד⡦ָדֹ׷ךַ
    ConnectableObservable idling =

    RxAbsListView.scrollEvents(listView)

    .map(event -> event.scrollState()

    == AbsListView.OnScrollListener.SCROLL_STATE_IDLE)

    .distinctUntilChanged()

    .publish();
    أؙٗ٦ٕךꟚ㨣⨡姺׾嗚濼ׅ׷0CTFSWBCMF

    View full-size slide

  76. 3Y+BWBד⡦ָדֹ׷ךַ
    ConnectableObservable idling =

    RxAbsListView.scrollEvents(listView)

    .map(event -> event.scrollState()

    == AbsListView.OnScrollListener.SCROLL_STATE_IDLE)

    .distinctUntilChanged()

    .publish();
    أؙٗ٦ٕךꟚ㨣⨡姺׾嗚濼ׅ׷0CTFSWBCMF

    View full-size slide

  77. 3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  78. 3Y+BWBד⡦ָדֹ׷ךַ
    أؙٗ٦ָٕ⨡姺׃׋׵ꬊず劍Ⳣ椚׾Ꟛ㨣ׅ׷
    final Subscription s = idling.startWith(true)

    .subscribe(l -> showLog("Success!"));

    View full-size slide

  79. 3Y+BWBד⡦ָדֹ׷ךַ
    أؙٗ٦ָٕ⨡姺׃׋׵ꬊず劍Ⳣ椚׾Ꟛ㨣ׅ׷
    final Subscription s = idling.startWith(true)

    .filter(b -> b)

    .subscribe(l -> showLog("Success!"));

    View full-size slide

  80. 3Y+BWBד⡦ָדֹ׷ךַ
    أؙٗ٦ָٕ⨡姺׃׋׵ꬊず劍Ⳣ椚׾Ꟛ㨣ׅ׷
    final Subscription s = idling.startWith(true)

    .filter(b -> b)

    .flatMap(aBool -> serivce.getData())

    .subscribe(l -> showLog("Success!"));

    View full-size slide

  81. 3Y+BWBד⡦ָדֹ׷ךַ
    أؙٗ٦ָٕꟚ㨣׃׋׵ꬊず劍Ⳣ椚׾⨡姺ׅ׷
    final Subscription s = idling.startWith(true)

    .filter(b -> b)

    .flatMap(aBool -> serivce.getData())

    .subscribe(l -> showLog("Success!"));

    View full-size slide

  82. 3Y+BWBד⡦ָדֹ׷ךַ
    أؙٗ٦ָٕꟚ㨣׃׋׵ꬊず劍Ⳣ椚׾⨡姺ׅ׷
    final Subscription s = idling.startWith(true)

    .filter(b -> b)

    .flatMap(aBool -> serivce.getData())
    .takeUntil(idling.filter(b -> !b))

    .repeatWhen(completes -> completes.switchMap(

    c -> idling.filter(b -> b)))

    .subscribe(l -> showLog("Success!"));

    View full-size slide

  83. 3Y+BWBד⡦ָדֹ׷ךַ
    أؙٗ٦ָٕꟚ㨣׃׋׵ꬊず劍Ⳣ椚׾⨡姺ׅ׷
    final Subscription s = idling.startWith(true)

    .filter(b -> b)

    .flatMap(aBool -> serivce.getData())
    .takeUntil(idling.filter(b -> !b))

    .repeatWhen(completes -> completes.switchMap(

    c -> idling.filter(b -> b)))

    .subscribe(l -> showLog("Success!"));

    View full-size slide

  84. 3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  85. 3Y+BWBד⡦ָדֹ׷ךַ
    أؙٗ٦ָٕ⨡姺׃׋׵ⱄTVCTDSJCFׅ׷
    final Subscription s = idling.startWith(true)

    .filter(b -> b)

    .flatMap(aBool -> serivce.getData())
    .takeUntil(idling.filter(b -> !b))

    .repeatWhen(completes -> completes.switchMap(

    c -> idling.filter(b -> b)))

    .subscribe(l -> showLog("Success!"));

    View full-size slide

  86. 3Y+BWBד⡦ָדֹ׷ךַ

    View full-size slide

  87. final Subscription s = idling.startWith(true)

    .filter(b -> b)

    .flatMap(aBool -> serivce.getData())
    .takeUntil(idling.filter(b -> !b))

    .repeatWhen(completes -> completes.switchMap(

    c -> idling.filter(b -> b)))

    .subscribe(l -> showLog("Success!"));
    3Y+BWBד⡦ָדֹ׷ךַ
    㹋遤ׅ׷أٖحس׾䭷㹀ׅ׷

    View full-size slide

  88. 3Y+BWBד⡦ָדֹ׷ךַ
    㹋遤ׅ׷أٖحس׾䭷㹀ׅ׷
    final Subscription s = idling.startWith(true)

    .subscribeOn(Schedulers.io())

    .filter(b -> b)

    .flatMap(aBool -> serivce.getData())

    .takeUntil(idling.filter(b -> !b))

    .repeatWhen(completes -> completes.switchMap(

    c -> idling.filter(b -> b)))

    .observeOn(AndroidSchedulers.mainThread())

    .subscribe(l -> showLog("Success!"));

    View full-size slide

  89. 3Y+BWBד⡦ָדֹ׷ךַ
    ConnectableObservable idling =

    RxAbsListView.scrollEvents(listView)

    .map(event -> event.scrollState()

    == AbsListView.OnScrollListener.SCROLL_STATE_IDLE)

    .distinctUntilChanged()

    .publish();

    subscriptions.add(idling.connect());


    subscriptions.add(idling.startWith(true)

    .subscribeOn(Schedulers.io())

    .filter(b -> b)

    .flatMap(aBool -> serivce.getData())

    .takeUntil(idling.filter(b -> !b))

    .repeatWhen(completes -> completes.switchMap(
    c -> idling.filter(b -> b)))

    .observeOn(AndroidSchedulers.mainThread())

    .subscribe(l -> showLog("Success!")));

    View full-size slide

  90. ًٔحز
    ˖ ؎كٝزװꬊず劍Ⳣ椚ָ䪔ְװְׅ
    ˖ 朐䡾㢌侧ָ㼰זֻג幥׬
    ˖ ر٦ةؿٗ٦ך鋅鸐׃ָ葺ֻז׷
    3Y+BWBךًٔحزرًٔحز

    View full-size slide

  91. ًٔحز
    ˖ ؎كٝزװꬊず劍Ⳣ椚ָ䪔ְװְׅ
    ˖ 朐䡾㢌侧ָ㼰זֻג幥׬
    ˖ ر٦ةؿٗ٦ך鋅鸐׃ָ葺ֻז׷
    رًٔحز
    ˖ 湫䠬涸הכꣲ׵זְ
    ˖ ⢪ְֿזׅחכ䢪׸ָ䗳銲
    ˖ ➬穈׫׾椚鍑׃גְזְה縐ח䅹׶װְׅ
    3Y+BWBךًٔحزرًٔحز

    View full-size slide

  92. ז׈㷕统؝أزָ넝ְךַ

    View full-size slide

  93. ˖ ؔلٖ٦ةָ׋ֻׁ׿֮׷
    ז׈㷕统؝أزָ넝ְךַ

    View full-size slide

  94. ˖ ؔلٖ٦ةָ׋ֻׁ׿֮׷
    ז׈㷕统؝أزָ넝ְךַ
    all()
    amb()
    ambWith()
    and()
    asyncAction()
    asyncFunc()
    averageDouble()
    averageFloat()
    averageInteger()
    averageLong()
    buffer()
    cache()
    cast()
    chunkify()
    collect()
    combineLatest()
    concat()
    concatMap()
    concatWith()
    connect()
    contains()
    count()
    countLong()
    create()
    debounce()
    defaultIfEmpty()
    defer()
    deferFuture()
    deferCancellableFuture()
    delay()
    dematerialize()
    distinct()
    distinctUntilChanged()
    doOnCompleted()
    doOnEach()
    doOnError()
    doOnNext()
    doOnRequest()
    doOnSubscribe()
    doOnTerminate()
    doOnUnsubscribe()
    doWhile()
    elementAt()
    elementAtOrDefault()
    empty()
    error()
    exists()
    filter()
    finallyDo()
    first()
    firstOrDefault()
    flatMap()
    flatMapIterable()
    forEach()
    forIterable()
    from()
    fromAction()
    fromCallable()
    fromCancellableFuture()
    fromFunc0()
    fromFuture()
    fromRunnable()
    generate()
    generateAbsoluteTime()
    getIterator()
    groupBy()
    groupByUntil()
    groupJoin()
    ifThen()
    ignoreElements()
    interval()
    isEmpty()
    join()
    just()
    last()
    lastOrDefault()

    View full-size slide

  95. ˖ ؔلٖ٦ةָ׋ֻׁ׿֮׷
    ˖ װװֿ׃ְ嚊䙀
    ז׈㷕统؝أزָ넝ְךַ

    View full-size slide

  96. ˖ ؔلٖ٦ةָ׋ֻׁ׿֮׷
    ˖ װװֿ׃ְ嚊䙀
    ˖ )PU$PME0CTFSWBCMF
    ˖ 4DIFEVMFS
    ˖ 4VCTDSJQUJPO
    ˖ 4VCKFDU
    ˖ #BDLQSFTTVSF
    ז׈㷕统؝أزָ넝ְךַ

    View full-size slide

  97. سًُؗٝز׾铣׬
    ؔلٖ٦ةך⹛ֹ׾䗰ד椚鍑ׅ׷
    ؔلٖ٦ةךؕذ؞ٔ׾濼׷
    ٓ؎ـٓٔ׾ⵃ欽ׅ׷
    嚂׃׬
    3Y+BWBך㷕统岀

    View full-size slide

  98. 3FBDUJWF93Y+BWB8JLJ
    IUUQTHJUIVCDPN3FBDUJWF9
    3Y+BWBXJLJ
    *OUSPEVDUJPOUP3Y
    IUUQXXXJOUSPUPSYDPN
    3Y4BNQMFT
    IUUQSYXJLJXJLJEPUDPN
    TBNQMFT
    سًُؗٝز׾铣׬

    View full-size slide

  99. 3Y+4ד鑐ׅ
    ˖ &4 #BCFM

    ˖ IUUQTKTGJEEMFOFUIZESBLFDBUGUWQIO
    ؔلٖ٦ةך⹛ֹ׾䗰ד椚鍑ׅ׷

    View full-size slide

  100. ˖ $SFBUJOH
    ˖ 5SBOTGPSNJOH
    ˖ 'JMUFSJOH
    ˖ $PNCJOJOH
    ˖ &SSPS)BOEMJOH
    ˖ $POEJUJPOBMBOE#PPMFBO
    ˖ .BUIFNBUJDBMBOE"HHSFHBUF
    ؔلٖ٦ةךؕذ؞ٔ׾濼׷

    View full-size slide

  101. א⟃♳ך0CTFSWBCMF׾⢪ְ׋ְ 

    ̔$PNCJOJOH$POEJUJPOBM
    אך0CTFSWBCMFח׃ַ莆㄂ָזְ 

    ̔5SBOTGPSNJOH'JMUFSJOH
    0CTFSWBCMF׾⡲׶׋ְ 

    ̔$SFBUJOH
    ؔلٖ٦ةךؕذ؞ٔ׾濼׷
    "%FDJTJPO5SFFPG0CTFSWBCMF0QFSBUPST
    IUUQSFBDUJWFYJPEPDVNFOUBUJPOPQFSBUPSTIUNM

    View full-size slide

  102. ˖ 0CTFSWBCMFDSFBUF
    ד0CTFSWBCMF׾⡲׵זְֿה☠
    ˖ ׋ְגְך׮ךכٓ؎ـٓٔח֮׷
    ˖ طحزٙ٦ؙ鸐⥋̔3FUSPGJU
    ˖ 42-̔42-#SJUF 0SNB
    ˖ 6*؎كٝز̔3Y#JOEJOH
    ˖ וֲ׃ג׮זְ㜥さכ0CTFSWBCMFGSPN9
    ׾⢪ֲ
    ˖ GSPN$BMMBCMF

    ˖ GSPN&NJUUFS

    ٓ؎ـٓٔ׾ⵃ欽ׅ׷

    View full-size slide

  103. 嚂׃׬
    IUUQTMJEFTDPNSPCXPSNBMEFWFSZUIJOHJTBTUSFBN

    ˖ 걧ך⢪ְ倯ָ殯ז׷
    ˖ ֲתֻ剅ֽ׷הֲ׸׃ְ
    ˖ 㔭׏׋׵BOESPJEKQ4MBDLפ

    IUUQTBOESPJEKQIFSPLVBQQDPN

    View full-size slide

  104. ˖ 3Y+BWB3$
    ˖ 3FBDUJWF4USFBNTك٦أ
    ˖ 'JOBM3FMFBTFTDIFEVMFEBUUI0DU
    3Y+BWBךֿ׸ַ׵

    View full-size slide

  105. ˖ 3Y+BWB3$
    ˖ 3FBDUJWF4USFBNTك٦أ
    ˖ 'JOBM3FMFBTFTDIFEVMFEBUUI0DU
    3Y+BWBךֿ׸ַ׵
    3FBDUJWF4USFBNT

    View full-size slide

  106. ˖ +BWBדך垥彊⻉ KVD'MPX

    ˖ IUUQTDPNNVOJUZPSBDMFDPNEPDT%0$
    ˖ 彊䬿׃גְ׷ٓ؎ـٓٔ
    ˖ "LLB4USFBNT
    ˖ 3FBDUPS
    ˖ 3Y+BWB
    3FBDUJWF4USFBNT

    View full-size slide

  107. ˖ +BWBדך垥彊⻉ KVD'MPX

    ˖ IUUQTDPNNVOJUZPSBDMFDPNEPDT%0$
    ˖ 彊䬿׃גְ׷ٓ؎ـٓٔ
    ˖ "LLB4USFBNT
    ˖ 3FBDUPS
    ˖ 3Y+BWB
    3FBDUJWF4USFBNT
    ״׶أةٝت٦سח

    View full-size slide

  108. ˖ 3FBDUJWFQSPHSBNNJOH8JLJQFEJB UIFGSFFFODZDMPQFEJB

    IUUQTFOXJLJQFEJBPSHXJLJ3FBDUJWF@QSPHSBNNJOH
    ˖ ++6(ش؎زإىش٦ד3FBDUJWF4USFBNTחאְג涪邌׃ת׃׋

    IUUQPLBQJFTIBUFCMPKQFOUSZ
    ˖ 3FBDUJWF9

    IUUQSFBDUJWFYJP
    ˖ &YQMPSJOH3Y+BWBGPS"OESPJE (050DQI0DUPCFS

    IUUQTTQFBLFSEFDLDPNKBLFXIBSUPOFYQMPSJOHSYKBWBGPS
    BOESPJEHPUPDQIPDUPCFS
    ˖ 3FBDUJWF1SPHSBNNJOHXJUI+%,'MPX"1*

    IUUQTDPNNVOJUZPSBDMFDPNEPDT%0$
    ⿫罋

    View full-size slide

  109. 5IBOL:PV
    랲䊛峔 吳䒭⠓爡'BCMJD

    !IZESBLFDBU
    https://github.com/hkurokawa
    https://speakerdeck.com/hkurokawa

    View full-size slide