Android meets RxJava - 渋谷Java#6

6,380 views
6,329 views

Published on

渋谷Java#6 で発表した資料です。

Published in: Technology
0 Comments
25 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,380
On SlideShare
0
From Embeds
0
Number of Embeds
2,476
Actions
Shares
0
Downloads
11
Comments
0
Likes
25
Embeds 0
No embeds

No notes for slide

Android meets RxJava - 渋谷Java#6

  1. 1. Android meets RxJava 渋谷Java #6 @yo_waka
  2. 2. freeeという会計サービスの会社で Android/iOSアプリを作っています 初めまして @yo_waka 若原 祥正 本当はJavaScriptが好き
  3. 3. まさか複数回OOMの話しが出 るようなガチなイベントだと思っ ていませんでした><
  4. 4. Androidでめんどくさいこと • 非同期なAPIを複数叩いて全て結果が うの を待ったり、エラー処理は1つにまとめたり • 複数の入力値を組み合わせてチェック • これらのテスト。。。
  5. 5. 愚直に書くとしんどいし 愚直に書くとクソコードに なりやすいところ
  6. 6. Androidで非同期処理の結果や 何らかの入力値のチェックを Streamぽくシンプルに統一的に書きたい
  7. 7. RxJava Netflix社が公開している Reactive Extension
  8. 8. Functional Reactive Programming については時間ないので
 ノータッチで
  9. 9. From Future to Observable Futureは入れ子になった非同期処理の扱い がムズい、またそれぞれの結果の条件で処 理を変えるとかしようとするとムズい。 (同期/非同期混じるとさらにムズい)
  10. 10. From Future to Observable Observableな結果オブジェクトのフィルタ、選択、変 換、結合、合成を行えるオペレーターのコレクションによっ て、同期/非同期を意識することなく扱えるようにする ! 注)java.util.Observableではなく、rx.Observableです
  11. 11. Observableを返すAPI設計に することで、様々な処理が統一 的に書けるようになる
  12. 12. 基本フロー Observable Publisher Observer #create Observable.OnSubscribe<T> #call #subscribe #onNext #onError #onCompleted Observer #call
  13. 13. 基本フロー + 結果をフィルタ Observable Publisher Observer #create Observable.OnSubscribe<T> #call #subscribe #onNext #onError #onCompleted Observer Func #call Failure Success
  14. 14. 基本フロー + 間に処理を挟む Observable Publisher Observer #create Observable.OnSubscribe<T> #call #subscribe #onNext #onError #onCompleted Observer Action #call
  15. 15. Observer、Subscriber、Func、Action 全てObservableなので再利用しやすい ! A->B、C->B、D->A->C みたいな場合、 無名クラスにしなければ再利用可能
  16. 16. 具体例
  17. 17. 認証とユーザー情報をまとめる public Observable<String> login(JsonObject params) { return http.request( Request.Method.POST, API_LOGIN_URL, params ).map(new LoginFunc()).flatMap(new Func1<Token, Observable<String>>() { @Override public Observable<String> call(Token token) { return http.request( Request.Method.GET, API_USER_INFO_URL, null ); } }); } ! public class LoginFunc implements Func1<String, Token> { @Override public Token call(String jsonResponse) { Gson gson = GsonFactory.getSimpleInstance(); Token token = gson.fromJson(jsonResponse, Token.class); // トークンのキャッシュとか ! return token;  } } レスポンスを モデルに変換 別のObservableを 直列にMapする
  18. 18. 使う側は処理を1つ書くだけ // Fragmentなどで viewModel.login(params).subscribe(new Observer<String>() { @Override public void onCompleted() {} ! @Override public void onError(Throwable throwable) { // エラー処理 } ! @Override public void onNext(String s) { // メインアクティビティへ遷移 startActivity(new Intent(getActivity(), MainActivity.class)); getActivity().finish(); } }); どのリクエストでエラーが 起きてもここに到達する
  19. 19. 自作のObservableを作る public static Observable<String> text(TextView view) { String currentText = String.valueOf(view.getText()); final BehaviorSubject<String> subject = BehaviorSubject.create(currentText); ! view.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {} ! @Override public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {} ! @Override public void afterTextChanged(Editable editable) { subject.onNext(editable.toString()); } }); ! return subject; } 入力値変更時にonNextを呼ぶ
  20. 20. 入力値によってメニューボタンを enabled/disabledにする Observable.combineLatest( MyObservable.text(dateInput), MyObservable.text(amountInput), new Func2<String, String>() { @Override public Boolean call(String issueDateStr, String amountStr) { long amount = NumberUtils.safeLongValueFromString(amountStr); return !Strings.isNullOrEmpty(issueDateStr) && amount > 0; } } ).subscribe(new Action1<Boolean>() { @Override public void call(Boolean enabled) { menuButton.setEnabled(enabled); } }); TextInputをObservableに してシリアル連結 最後のFunc#callの返り値が引数 として渡る ここまでの結果がそれぞれ引数と して入ってくる
  21. 21. テストもシンプルに書ける dateInput.setText(“2014/05/31”); amountInput.setText(null); ! assertThat(menuButton).isDisabled(); ! amountInput.setText(“50000”); ! // 特にイベント発火やメソッド分割する手間もいらない assertThat(menuButton).isEnabled();
  22. 22. RxJava-Android Observer、Subscriberそれぞれどのスレッド で実行するかを選択できる(重要!)。 // 別スレッドでSubscriberを実行 observer.subscribeOn(Schedulers.newThread()); ! // メインスレッドでObserverを実行 observer.observeOn(AndroidSchedulers.mainThread());
  23. 23. 使ってみて • 学習コストは高いけど慣れてきて上手くコ ンポーネント化できると楽しい • 閲覧だけのシンプルなアプリならEventBus でもいいかも • ちょっと複雑な入力系のアプリならおすす め
  24. 24. Reactive周りが熱い Reactive Stream  JVM上のノンブロッキングなストリーム処理を標準化 するプロジェクト  最終的にJSRでの標準化を目指してるらしい  Typesafe社を中心としてJVMの非同期処理周りのメイ ンプレーヤーが勢 いしているぽい  RxJavaの作者も入ってる
  25. 25. せっかくなので宣伝 6月から五反田にオフィス移転するので、Android/ Gradleとかモバイルトークしたい方いればいつで も遊びに来てください! ※ 20時前後くらいに来るとご飯食べられるらしい です
  26. 26. ありがとうございました

×