SlideShare a Scribd company logo
RxJava on Android 
2014/10/28 @yo_waka
はじめまして 
若原 祥正 
@yo_waka 
• freeeという会計サービスの会社で 
Android/iOSアプリを作っています
ちょっとだけ宣伝 
• 個人事業主の確定申告、 
小規模法人の決算をもっと 
カンタンに 
• PC,モバイルはこだわらず、 
どこでもどのデバイスでも帳 
簿をつけられるよ
RxJavaの使いどころ 
• MVVMのつなぎとして使っています 
• FragmentからViewの状態変更を監視してコール 
バック実行 
• ViewModelからAPIリクエストの結果を 
Fragmentに返す 
• ViewModelの状態をFragmentに反映させる 
! 
• それぞれのインターフェースをObservableで統一
RxJavaでMVVM 
Observable 
Activity/ ViewModel Model 
Fragment 
Observable Observable 
CustomView API Client
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() を呼ぶ 
} 
}
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); 
} 
}
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); 
} 
}
RxAndroidについて
RxAndroid 
• RxJavaのAndroid向けバインディングを提供して 
くれるライブラリ 
• RxJavaと時を同じくしてio.reactivexに移った 
• Undocumented!! 
compile 'io.reactivex:rxandroid:0.22.0'
実行スレッドの指定 
• SubscriberとObserverの実行スレッドを指定できる 
(AndroidSchedulerというユーティリティも提供) 
• APIコールなど非同期処理をSubscribeする場合はこい 
つで 
Observable.from("one", "two", "three", "four", "five") 
.subscribeOn(Schedulers.io()) 
.observeOn(AndroidSchedulers.mainThread()) 
.subscribe(/* an Observer */);
ハマりどころ 
• Activity, Fragment上で実行する場合は注意が必要 
• Subscriber実行中に画面回転などが起きると、 
Fragmentが破棄された状態でコールバックが実行 
されてNullPointerExceptionが起きがち 
• 気にしていても忘れがちなので何とかしたい
Activity,Fragmentの 
バインディング 
• 実行前にactivity.isFinishing()、 
fragment.isAdded()をチェック 
• ライフサイクルを気にせずObserveできて便利 
AndroidObservable.bindFragment( // bindActivityもあるよ 
this, 
viewModel.getList() 
) 
.subscribeOn(Schedulers.io()) 
.subscribe(/* an Observer */); // 自動でmainThreadで実行
便利な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() 
));
便利な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) {} 
});
まとめ 
• RxAndroidはAndroidでRxJavaのお供に 
特にAndroidSchedulerは便利 
• 用意されているOperatorは便利だけど実装小さい 
ので自分で作るのと大して変わらない 
• クラスファイルはどれも小さいので自前のRx実装 
の参考にもしやすい 
• ドキュメントは無いけど
ありがとうございました

More Related Content

RxJava on Android

  • 1. RxJava on Android 2014/10/28 @yo_waka
  • 2. はじめまして 若原 祥正 @yo_waka • freeeという会計サービスの会社で Android/iOSアプリを作っています
  • 3. ちょっとだけ宣伝 • 個人事業主の確定申告、 小規模法人の決算をもっと カンタンに • PC,モバイルはこだわらず、 どこでもどのデバイスでも帳 簿をつけられるよ
  • 4. RxJavaの使いどころ • MVVMのつなぎとして使っています • FragmentからViewの状態変更を監視してコール バック実行 • ViewModelからAPIリクエストの結果を Fragmentに返す • ViewModelの状態をFragmentに反映させる ! • それぞれのインターフェースをObservableで統一
  • 5. RxJavaでMVVM Observable Activity/ ViewModel Model Fragment Observable Observable CustomView API Client
  • 6. 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() を呼ぶ } }
  • 7. 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); } }
  • 8. 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); } }
  • 10. RxAndroid • RxJavaのAndroid向けバインディングを提供して くれるライブラリ • RxJavaと時を同じくしてio.reactivexに移った • Undocumented!! compile 'io.reactivex:rxandroid:0.22.0'
  • 11. 実行スレッドの指定 • SubscriberとObserverの実行スレッドを指定できる (AndroidSchedulerというユーティリティも提供) • APIコールなど非同期処理をSubscribeする場合はこい つで Observable.from("one", "two", "three", "four", "five") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(/* an Observer */);
  • 12. ハマりどころ • Activity, Fragment上で実行する場合は注意が必要 • Subscriber実行中に画面回転などが起きると、 Fragmentが破棄された状態でコールバックが実行 されてNullPointerExceptionが起きがち • 気にしていても忘れがちなので何とかしたい
  • 13. Activity,Fragmentの バインディング • 実行前にactivity.isFinishing()、 fragment.isAdded()をチェック • ライフサイクルを気にせずObserveできて便利 AndroidObservable.bindFragment( // bindActivityもあるよ this, viewModel.getList() ) .subscribeOn(Schedulers.io()) .subscribe(/* an Observer */); // 自動でmainThreadで実行
  • 14. 便利な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() ));
  • 15. 便利な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) {} });
  • 16. まとめ • RxAndroidはAndroidでRxJavaのお供に 特にAndroidSchedulerは便利 • 用意されているOperatorは便利だけど実装小さい ので自分で作るのと大して変わらない • クラスファイルはどれも小さいので自前のRx実装 の参考にもしやすい • ドキュメントは無いけど