RxJavaでAsynchronousなAndroidアプリを開発しました

  • このエントリーをはてなブックマークに追加

読了時間10分

初めまして!白ヤギコーポレーションのAndroidエンジニア、ニコです!

最近アップデートしたカメリオAndroid版はUIだけではなくて、データフローも変わりました。
カメリオAndroidでReactiveX(Reactive Extension)というAPIのJavaバージョン(RxJava)が導入されました。

RxJava

RxJavaはAsynchronousプログラミングのAPIです。ObservablesでAsynchronousデータの流れを表します。Observablesも色んなオペレータがあって、オペレータでObservableをフィルター、選択、変換、構成、そして組み合わせすることができます。

Observables

Observableとは?

ObservableというObjectはタスクが終わったあとにSubscriberに通知して、SubscriberはObservableが発するものを操作します。
Observableは一つのタスクを待たずにSubscriberを使って、SubscriberがObservableを監視して、Observableのタスクが終わったら、Observableの結果をSubscriberにパスします。そのように、他のタスクをブロックしないので、複数のタスクを同時に操作することができます。

Observable
.create(subscriber -> subscriber.onNext("カメリオ"))
.subscribe(text -> Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT));

このコードで「カメリオ」Stringを発するObservableを作って、SubscriberがそのStringを受け取って、そのStringからToastを表示します。

Observableを変換する

Observableを変換する機能は多いですが、以下の三つの機能が最も採用されていると思います:

map():
Mapという機能はObservableが発するものを変換して、同じタイプのものをreturnするか別のタイプのものもreturnすることができます

flatMap():
FlatMapという機能はObservableが発するものから他のObservableを作って、元のObservableをその新しいObservableに変換します。
switchMap():
SwitchMapという機能はFlatMapに似ているのですが、SwitchMapは一番新しいObservableだけを操作します。

Observable.
create(subscriber -> subscriber.onNext("カメリオ"))
.map(text -> text + " Android");

このコードでObservableが「カメリオ」Stringを発して、Map機能がそのStringを変換して、「 Android」Stringを連結して、最後にObservableが「カメリオ Android」を発します。

ダイアグラム:
Screen Shot 2015-07-06 at 09.19.15

Observableをフィルターする

Observableが発するものもフィルタすることができます。例えば:

Observable.from(new String[]{"Google", "Apple", "Android", "Java"})
.filter(new Func1<String, Boolean>() {
@Override
public Boolean call(String text) {
return !text.equals("Apple");
}
})

このコードでObservableが[ “Google”, “Apple”, “Android”, “Java”]のString Arrayを発して、Filter機能がチェックして、もしStringが「Apple」だったら、発しません。

ダイアグラム:
Screen Shot 2015-07-06 at 09.19.37

AndroidのActivity/Fragment Lifecycleに関して

Androidアプリは普通のJavaアプリと違って、Activity/FragmentのLifecycleがあります。
例えばサーバーから取ったデータをUIに表示しますが、それはActivity/Fragmentがまだアクティブな状態の間だけ可能です。なので、エラーを防ぐ為にActivity/Fragmentが破壊される前にObservableからunsubscribeしてください。
例:

@Override
protected void onDestroy() {
helloSubscription.unsubscribe();
super.onDestroy();
}

幸いにもこのケースの為にHelper機能があります。
ObservableのSubscriberを登録する時にAppObservable.bindActivity()/bindFragment()という機能を使って、その機能がActivity/Fragmentが破壊される前にそのObservableをunsubscribeします。そうするとObservableがSubscriberに通知しません。

Threadに関して

もしObservableにどんなThreadでsubscribeするか、もしくはobserveするかを特定しない場合に、Observableがタスクを行うか、もしくは結果をパスする時にAndroidのMain Threadを使います。私の意見では、それはあまり良くないことと考えています。全部のタスクがMain Threadで行われたらアプリが重くなり、ユーザーからしてもあまりよくないので、subscribeOn()とobserveOn()機能を使って、Threadを特定してください。
例えば、subscribeOn(Schedulers.io())observeOn(AndroidSchedulers.mainThread()).

出典
https://github.com/ReactiveX/RxJava/wiki
https://groups.google.com/forum/#!forum/rxjava

最先端情報吸収研究所 – AIAL

際限ない情報の中から、自分に価値のある情報を効果的に吸収することは、かつてなく大きなチャレンジです。最先端情報研究所はニュースアプリ「カメリオ」、レコメンドエンジン「カメクト」を提供する白ヤギコーポレーションのR&D部門として、データサイエンスの力でこの問題を解決していきます。白ヤギでは現在研究開発メンバーを募集しております。ご興味のある方は是非下記サイトを御覧ください!

Date:2015-07-10 Posted in:Android アプリ・製品 Text by: