RxJava on Android

17
RxJava on Android 2014/10/28 @yo_waka

description

RxJava NightのLTで発表した資料です。

Transcript of RxJava on Android

Page 1: RxJava on Android

RxJava on Android2014/10/28 @yo_waka

Page 2: RxJava on Android

はじめまして

@yo_waka

若原 祥正

• freeeという会計サービスの会社でAndroid/iOSアプリを作っています

Page 3: RxJava on Android

ちょっとだけ宣伝

• 個人事業主の確定申告、小規模法人の決算をもっとカンタンに

• PC,モバイルはこだわらず、どこでもどのデバイスでも帳簿をつけられるよ

Page 4: RxJava on Android

RxJavaの使いどころ• MVVMのつなぎとして使っています

• FragmentからViewの状態変更を監視してコールバック実行

• ViewModelからAPIリクエストの結果をFragmentに返す

• ViewModelの状態をFragmentに反映させる !

• それぞれのインターフェースをObservableで統一

Page 5: RxJava on Android

RxJavaでMVVM

ViewModel ModelActivity/Fragment

CustomView API Client

ObservableObservable

Observable

Page 6: RxJava on Android

API Client• APIを叩いた結果をObservableで返す

protected Observable<String> request(final int method, final String path) { return Observable.create(new RequestSubscriber(method, path)) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()); } // Observable.OnSubscribeを実装したクラスはObservableにできる public class RequestSubscriber implements Observable.OnSubscribe<String> { @Override public void call(final Subscriber<? super String> subscriber) { // リクエストのコールバックで // subscriber.onNext(string), subscriber.onCompleted() を呼ぶ } }

Page 7: RxJava on Android

ViewModel• APIクライアントの結果を処理するObservableを返す

public Observable<Item> getItems(String name) { return apiClient.request(Request.Method.POST, API_URL) .map(new GettingItemFunc()) /* doOnNextの前に処理を挟む */ .doOnError(new ErrorHandler()); /* エラー処理 */ } // callメソッドに渡す引数の数に応じて、Func0~Nまであるよ! private class GettingItemsFunc implements Func1<String, List<Item>> { @Override public List<Item> call(String jsonResponse) { Gson gson = GsonFactory.getInstance(); itemList = gson.fromJson(jsonResponse, ItemList.class); } }

Page 8: RxJava on Android

Fragment• APIクライアントの結果を処理するObservableを返す

public Observable<Item> getItems(String name) { return apiClient.request(Request.Method.POST, API_URL) .map(new GettingItemFunc()) /* doOnNextの前に処理を挟む */ .doOnError(new ErrorHandler()); /* エラー処理 */ } private class GettingItemsFunc implements Func1<String, List<Item>> { @Override public List<Item> call(String jsonResponse) { Gson gson = GsonFactory.getInstance(); itemList = gson.fromJson(jsonResponse, ItemList.class); } }

Page 9: RxJava on Android

RxAndroidについて

Page 10: RxJava on Android

RxAndroid• RxJavaのAndroid向けバインディングを提供してくれるライブラリ

• RxJavaと時を同じくしてio.reactivexに移った

• Undocumented!!

compile 'io.reactivex:rxandroid:0.22.0'

Page 11: RxJava on Android

実行スレッドの指定• SubscriberとObserverの実行スレッドを指定できる (AndroidSchedulerというユーティリティも提供)

• APIコールなど非同期処理をSubscribeする場合はこいつで

Observable.from("one", "two", "three", "four", "five") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(/* an Observer */);

Page 12: RxJava on Android

ハマりどころ

• Activity, Fragment上で実行する場合は注意が必要

• Subscriber実行中に画面回転などが起きると、Fragmentが破棄された状態でコールバックが実行されてNullPointerExceptionが起きがち

• 気にしていても忘れがちなので何とかしたい

Page 13: RxJava on Android

Activity,Fragmentの バインディング

• 実行前にactivity.isFinishing()、fragment.isAdded()をチェック

• ライフサイクルを気にせずObserveできて便利

AndroidObservable.bindFragment( // bindActivityもあるよ this, viewModel.getList() ) .subscribeOn(Schedulers.io()) .subscribe(/* an Observer */); // 自動でmainThreadで実行

Page 14: RxJava on Android

便利なOperator• OperatorConditionalBinding便利条件付きObserverをカンタンに作れるfalseが返された時は自動でunsubscribe()も呼ばれて素敵

public class Validator implements Func1<SomeClass, Boolean>() { @Override public Boolean call(SomeClass obj) { return obj.isValid(); } }; viewModel.createNew() .subscribe(new Observer<List<Deal>>() { /** do something */ }) .lift(new OperatorConditionalBinding<T, SomeClass>( new SomeClass(), new Validator() ));

Page 15: RxJava on Android

便利なOperator• ViewObservableでView,TextView,AdapterViewなどのイベントをバインドできる

ViewObservable.clicks(view, false).subscribe(new Observer<OnClickEvent>() { @Override public void onNext(OnClickEvent evt) {} }); ViewObservable.text(inputView, false) .delay(1000, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) // これを忘れると動かない .subscribe(new Observer<String>() { @Override public void onNext(String s) {} }); ViewObservable.itemClicks(adapter, false).subscribe(new Observer<OnItemClickEvent>() { @Override public void onNext(OnItemClickEvent evt) {} });

Page 16: RxJava on Android

まとめ• RxAndroidはAndroidでRxJavaのお供に特にAndroidSchedulerは便利

• 用意されているOperatorは便利だけど実装小さいので自分で作るのと大して変わらない

• クラスファイルはどれも小さいので自前のRx実装の参考にもしやすい

• ドキュメントは無いけど

Page 17: RxJava on Android

ありがとうございました