Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Androidアプリ開発で
RxJavaを活用する
3つのユースケース
Hiroyuki Kusu ( @hkusu_ )
2016/06/23 potatotips #30
①非同期処理の結果うけとり
②イベントの送信/購読
③データの変更監視
※今回はデータ加工、FRP的な話はしません
※本スライド上のサンプルコードは Java 8 および
Retrolambda の利用を前提としています
①非同期処理の結果うけとり
②イベントの送信/購読
③データの変更監視
doSomethingAsnc()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aStringList -> {
// ...
Observable.create(subscriber -> {
// ... 裏スレッドで何か
subscriber.onNext("something");
subscriber.onCompleted();
})
.subscribeO...
①非同期処理の結果うけとり
②イベントの送信/購読
③データの変更監視
購読側
イベント仲介用のクラス
(シングルトン)
Subject
送信側
早い話が Otto や EventBus のようなもの
コールバックを引き回すのが煩雑な場合に
(例:Activity 間の通知、ListViewの操作イベント取得など)...
public class RxEventBus {
private final Subject<Object, Object> subject
= new SerializedSubject<>(PublishSubject.create())...
public class RxEventBus {
private final Subject<Object, Object> subject
= new SerializedSubject<>(PublishSubject.create())...
public class RxEventBus {
private final Subject<Object, Object> subject
= new SerializedSubject<>(PublishSubject.create())...
rxEventBus.post(new SomeEvent());
rxEventBus.onEvent(SomeEvent.class, event -> {
// … 結果を受け取って何か
});
イベントの送信
イベントの購読
イベント仲...
①非同期処理の結果うけとり
②イベントの送信/購読
③データの変更監視
データを保持するクラス
Subject購読側
購読
データ変更
public class SomeRepository {
private final Subject<String, String> subject
= new SerializedSubject<>(PublishSubject.creat...
public class SomeRepository {
private final Subject<String, String> subject
= new SerializedSubject<>(PublishSubject.creat...
public class SomeRepository {
private final Subject<String, String> subject
= new SerializedSubject<>(PublishSubject.creat...
someRepository.getObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aString...
データを保持するクラス
Activity/
Fragment 購読
ビューへの反映
何かしらの
CRUD操作
データ
『データに対する』ビューの描画処理が宣言的に定義できる。
データの流れが一方向なので分かりやすい
関心の分離
TIPS
・購読の一括解除ができる
・Activity の onPause() 等で購読を停止
したい場合、一度 unscribe() すると add()
できなくなる問題
⇒ unsubscribe() でなく clear() を使う
Composit...
doSomethingAsnc()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aStringList -> {
// ...
public class Tuple3<T1, T2, T3> {
private final T1 t1;
private final T2 t2;
private final T3 t3;
private Tuple3(T1 t1, T2 ...
Sample code
hkusu/android-rxjava-app-sample
THANKS!
予備スライド
Activity/Fragment
UseCase層
Repository層
Service層
(AndroidのServiceではない)
DI DI DI
Observable<T>
Observable<T>
Observable<T>
裏...
【Potatotips #30】RxJavaを活用する3つのユースケース
Upcoming SlideShare
Loading in …5
×

【Potatotips #30】RxJavaを活用する3つのユースケース

2,234 views

Published on

2016/06/23(Thu)に開催された potatotips #30 (http://potatotips.connpass.com/event/32665/) での発表資料です。

Published in: Technology
  • Be the first to comment

【Potatotips #30】RxJavaを活用する3つのユースケース

  1. 1. Androidアプリ開発で RxJavaを活用する 3つのユースケース Hiroyuki Kusu ( @hkusu_ ) 2016/06/23 potatotips #30
  2. 2. ①非同期処理の結果うけとり ②イベントの送信/購読 ③データの変更監視 ※今回はデータ加工、FRP的な話はしません ※本スライド上のサンプルコードは Java 8 および Retrolambda の利用を前提としています
  3. 3. ①非同期処理の結果うけとり ②イベントの送信/購読 ③データの変更監視
  4. 4. doSomethingAsnc() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(aStringList -> { // … 結果を受け取って何か }); コールバックを廃して同期的に書ける Observable<T>を返す非同期な処理
  5. 5. Observable.create(subscriber -> { // ... 裏スレッドで何か subscriber.onNext("something"); subscriber.onCompleted(); }) .subscribeOn(Schedulers.io()) // 裏スレッドを指定 .observeOn(AndroidSchedulers.mainThread()) // メインスレッドを指定 .subscribe(res -> { // ... メインスレッドで結果を受け取って何か }); ちなみに重たい処理を裏スレッドで実行させたい 時にも使える(AsyncTask、AsyncTaskLoaderの替り)
  6. 6. ①非同期処理の結果うけとり ②イベントの送信/購読 ③データの変更監視
  7. 7. 購読側 イベント仲介用のクラス (シングルトン) Subject 送信側 早い話が Otto や EventBus のようなもの コールバックを引き回すのが煩雑な場合に (例:Activity 間の通知、ListViewの操作イベント取得など) イベントの送信 イベントの購読
  8. 8. public class RxEventBus { private final Subject<Object, Object> subject = new SerializedSubject<>(PublishSubject.create()); public <T> Subscription onEvent(Class<T> clazz, Action1<T> handler) { return subject .ofType(clazz) .subscribe(handler); } public void post(Object event) { subject.onNext(event); } } RxEventBus.java(前項におけるイベント仲介用のクラス) 内部にSubjectを保持 継続的にイベントを発生させるには Subject を用いる
  9. 9. public class RxEventBus { private final Subject<Object, Object> subject = new SerializedSubject<>(PublishSubject.create()); public <T> Subscription onEvent(Class<T> clazz, Action1<T> handler) { return subject .ofType(clazz) .subscribe(handler); } public void post(Object event) { subject.onNext(event); } } RxEventBus.java(前項におけるイベント仲介用のクラス) イベントの購読用メソッド イベントクラス名でフィルタ
  10. 10. public class RxEventBus { private final Subject<Object, Object> subject = new SerializedSubject<>(PublishSubject.create()); public <T> Subscription onEvent(Class<T> clazz, Action1<T> handler) { return subject .ofType(clazz) .subscribe(handler); } public void post(Object event) { subject.onNext(event); } } RxEventBus.java(前項におけるイベント仲介用のクラス) イベントの送信用メソッド
  11. 11. rxEventBus.post(new SomeEvent()); rxEventBus.onEvent(SomeEvent.class, event -> { // … 結果を受け取って何か }); イベントの送信 イベントの購読 イベント仲介用のクラスのインスタンスを共有(シングルトン等)し ておけば、アプリケーションのどこからでもイベントを送れる
  12. 12. ①非同期処理の結果うけとり ②イベントの送信/購読 ③データの変更監視
  13. 13. データを保持するクラス Subject購読側 購読 データ変更
  14. 14. public class SomeRepository { private final Subject<String, String> subject = new SerializedSubject<>(PublishSubject.create()); public final Observable<String> getObservable() { return subject; } private void notify(String string) { subject.onNext(string); } // ... 以降、CRUDのコード } 内部にSubjectを保持 SomeRepository.java(前項におけるデータを保持するクラス)
  15. 15. public class SomeRepository { private final Subject<String, String> subject = new SerializedSubject<>(PublishSubject.create()); public final Observable<String> getObservable() { return subject; } private void notify(String string) { subject.onNext(string); } // ... 以降、CRUDのコード } SomeRepository.java(前項におけるデータを保持するクラス) SubjectをObservable<T> として外部へ公開
  16. 16. public class SomeRepository { private final Subject<String, String> subject = new SerializedSubject<>(PublishSubject.create()); public final Observable<String> getObservable() { return subject; } private void notify(String string) { subject.onNext(string); } // ... 以降、CRUDのコード } SomeRepository.java(前項におけるデータを保持するクラス) データ変更を通知する private メソッド ※データのCRUD時に notify() をコールする規則とする
  17. 17. someRepository.getObservable() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(aString -> { // ... 結果を受け取って何か }); 購読側 データが変更される度にストリームが 流れてくる
  18. 18. データを保持するクラス Activity/ Fragment 購読 ビューへの反映 何かしらの CRUD操作 データ 『データに対する』ビューの描画処理が宣言的に定義できる。 データの流れが一方向なので分かりやすい 関心の分離
  19. 19. TIPS
  20. 20. ・購読の一括解除ができる ・Activity の onPause() 等で購読を停止 したい場合、一度 unscribe() すると add() できなくなる問題 ⇒ unsubscribe() でなく clear() を使う CompositeSubscription
  21. 21. doSomethingAsnc() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(aStringList -> { // ... 結果を受け取って何か }); 型名を示す変数名をつけると分かりやすいかも? Retrolambda を利用していてストリーム中 のデータの型がよく分からなくなる問題 例)List<String> の場合
  22. 22. public class Tuple3<T1, T2, T3> { private final T1 t1; private final T2 t2; private final T3 t3; private Tuple3(T1 t1, T2 t2, T3 t3) { this.t1 = t1; this.t2 = t2; this.t3 = t3; } public T1 get1() { return t1; } public T2 get2() { return t2; } public T3 get3() { return t3; } public static <T1, T2, T3> Tuple3<T1, T2, T3> create(T1 t1, T2 t2, T3 t3) { return new Tuple3<>(t1, t2, t3); } } 3つ以上の時は Tuple 的なクラスを用意する Observable<T> で複数の値を扱いたい場合 Observable<Pair<String, List<Integer>>> 2つの場合は Pair が使える
  23. 23. Sample code hkusu/android-rxjava-app-sample
  24. 24. THANKS!
  25. 25. 予備スライド
  26. 26. Activity/Fragment UseCase層 Repository層 Service層 (AndroidのServiceではない) DI DI DI Observable<T> Observable<T> Observable<T> 裏スレッド( Schedulers.io() )で実行 メインスレッド ( AndroidSchedulers .mainThread() )で購読

×