はじめに
仕事で作っているアプリで非同期処理のコールバックが地獄めいてきて吐きそうになったので そのあたりをバッチリ解決するためのアレコレを模索していた。
そんな折にKeithYokomaさんがQiitaに海外記事の翻訳を公開したのを読んで、一念発起したという具合です。
EventBusを使う方法も考えたのだけど、あれはLocalBroadcast使うまでもないときに発動させるのがいいんだろうな、という感想です。
そんなわけで、色々と見たこと・考えたことを備忘録としてまとめました。
参考にしたサイトたち
だいたいこれ読んどけばOKみたいなそんな感じです。
入門
- ReactiveExtensions - 【翻訳】AsyncTask と AsyncTaskLoader を rx.Observable に置き換える - RxJava Android Patterns - Qiita
- 「RxJava?なにが便利やねん」というところで拒否しているのであればこれ読んで考えを改め一歩踏み出すことができる。
- RxAndroidをカジュアルに使ってみるとか - みんからきりまで
- とてもわかり易かった。入門として最適。
応用例とか
- Model-Contoller間の通知処理をObserver PatternでやっていたのをRxAndroidを使って書き直してみた。 - Qiita
- Android - RxJavaでAPIクライアントを作る - Qiita
- Grokking RxJava, Part 4: Reactive Android
お役立ち
- Observable Utility Operators · ReactiveX/RxJava Wiki
- neue cc - Reactive Extensions入門 + メソッド早見解説表
- Rx逆引き : Learn Reactive Extensions
- Observablesでなんか便利なメソッドないかな〜と探すときにおすすめ。特に下のリンク先はある程度Rx慣れたなら必読。
- ただしJavaのそれと完全一致ではないので、広い心を持ってうまく理解する力が必要。
ハマリポイントつぶし
- AndroidObservable.bindActivityは自動でobserveOn(mainThread())してしまうのでその後にmap等をつなげるとUIスレッドで実行される - visible true
- 名前変わって
AppObservable.bindActivity
はAndroidではよく使うので、正しく理解して使いたい。 - しかしながらコード読むと実は大したことしてない(でもうまい使い方だと思った)のでコード読むが吉
その他
- RxAndroid/rxandroid-framework/src/main/java/rx/android/app at 0.x · ReactiveX/RxAndroid
- いいのさんに教えてもらった。なにやら良さそうなにおいがする
理解したことの整理
Reactive ExtensionsはPromiseパターンに似てる
もともとJavaScriptのPromiseパターンは理解していた(AngularJSでは頻出)ので、それと対比して関連付けて着目することが多かった。 Rx == Promise ではない気がする。じゃないとRxJSみたいなものがなんで存在しているのかわからないです。。
RxはPromise++でありcallback++である、と記されたサイトがあった。そういう感じだと思った。
JavaScriptでは(俺の観測範囲では)すべてが非同期で、UIスレッドがどうの〜ということがないし、 適切なコールバックを使うことがある種の慣習となっているので、Promiseの概念は取っ付き易いんだと思う。
一方でスマホアプリはUIスレッドで同期命令を実行すればその間の描画がフリーズする。 なのでそういう命令を使うならば別スレッドで処理を実行し、結果をUIスレッド側にコールバックする必要がある。 そのため、どのスレッドにいるのかを意識してコーディングしないといけないし、スレッドのきめ細やかな調整がとても大事なのだと思う。
RxAndroidはAsyncTaskLoaderを置き換えることができる
詳細はKeithYokomaさんが訳した記事を読んでいただくとして。とにかくAsyncTaskLoaderはつらい。 「開始」「終了」「リセット」くらいしかコールバックを得られないうえ、画面回転の対応も微妙。 柔軟に扱えるようにするにはかなりいろんなことをしないといけなくて、ないよりマシだけどつらい。
しかしRxAndroidなら、(ちゃんとObservableを定義すれば)レスポンス値を見てエラーにできるし、 飛んできたデータに対する加工も簡単。Observableの開始時や終了時に何か実行させたいとか、 いろんなところでコールバックを受けることができるので柔軟性が高い。
AppObservable.bindActivity/bindFragment はハマることがあるので気をつける
詳しくはsys1yagiさんの記事を。
すべてのAsyncTaskLoaderを追放できるか?
日和った答えとしては、まぁちょっとずつやっていくかー。という感想。 RxJavaおぢさんとしてすべての非同期タスクをRxで書いて問題あるのかないのか、まだ答えを出しかねている状態。 あとRxAndroidがまだまだ破壊的変更あったりするというのも気になる(がgradleでバージョン固定できるからそこはまぁ気合でなんとかなる)。
まとめ
という具合です。