LoginSignup
5
5

More than 5 years have passed since last update.

Android開発でとりあえずRxを使ってみたい人向けRxJava入門【2.実装編】

Last updated at Posted at 2018-12-05

今回の話

【1.概要編】の続き

実装

【1.概要編】で書いた通りにストリームを利用してプログラミングをしていきたい場合、以下の3つの手順があると思っています。

1. ストリームを生成する
2. データソースを設定する
3. ストリームを操作する

この3つの手順を実現するために様々な方法があることが学習コストを引き上げる要因な気がしますので、一つ一つ解説していきます。
(参考:RxJava javadoc)
http://reactivex.io/RxJava/2.x/javadoc/

1.ストリームを生成する

多分以下の5種類があります。

クラス名 概要
Observable ストリーム生成の基本。基本的にはこのクラスを利用してストリームを生成する
Single Observableと同様にストリームを生成できる。ただし、以下の点が異なる
1.単一のインスタンスしか渡せない
2.一度イベントが発生した後は購読しない
絶対に一回しかデータが来ない(APIレスポンスを流すだけとか)というときはこちらを使うイメージ。
Maybe ほぼほぼSingleと同じ。ただし"データを流さず終了"という選択ができる
Completable 値を返さないストリーム。処理はしたい別に画面表示しないし...というときに使うイメージ。
Flowable 値の流入を制限できるストリーム。すっごい数のデータが来る可能性があればこちらを使うイメージ。

例えばSingleを使うと、一回しかデータが流れてこないことが確実なので「次またデータが流れてきた場合」のことを考えずに済みます。

そのため場合によってストリーム生成するクラスを書き分けた方が良いとは思うのですが、要するに基本的にはObservableで全て実現できるので、まず書き始めるときはObservable一択でよいと思っています。

2.データソースを設定する

データソースというのはストリームに流れるデータの元です。
後述しますが、createというAPIを使って以下のようにデータソースを設定してみます。

 val stream = Observable.create<SensorEvent> { subscriber ->

        val obj = object : SensorEventListener {
            override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {

            }

            // 端末のセンサーが変更されたときに呼ばれるイベント
            override fun onSensorChanged(event: SensorEvent?) {
                if (event != null) subscriber.onNext(event)
            }
        }

        sensorManager.registerListener(obj, sensor, SensorManager.SENSOR_DELAY_NORMAL)

    }!!

このデータソースは"Android端末のセンサーイベント"になります。データソース上は端末のセンサーが反応すればデータが発生していますが、それはまだストリーム上に流れていません。データソース上からストリームにデータを流すには以下の処理が必要です。

subscriber.onNext(event)

ちなみに、もうデータを流したくないよ!というときは以下の記載をします。

subscriber.onComplete()

エラーが発生したよ!というときのフローも用意されています。以下のように記載します。

subscriber.onError()

上記のようにストリームに流すデータの大元の設定が必要です。
代表的なものを以下に記載します。

API名 概要
just 単一のデータ一つを流す。
fromArray 配列のデータを流す。
create どんなデータを流すか自由に書ける。

3. ストリームを操作する

データソースを設定してストリームにデータが流れてきました。この状態のストリームに対して様々な操作を行うことができます。

map

代表的なmap APIについて記載します。公式のJavaDocには以下のような図で表されています。

map.png
参照:https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/map.png

例えばストリームにStringデータが流れてきたときにそれをIntデータが流れるストリームにしたい場合は以下のように記載します。


Observable.just("1").map{ item -> item.toInt() }

上記図の通り、ストリームに対してmapAPIを通じて新しくIntが流れるストリームが生成されるようなイメージです。
このようにストリームを操作していくことでほしいデータが流れるようにしていくことができます。

flatmap

RxJavaには非常に多くのAPIが用意されているので様々な操作が可能ですが、
基本的にflatmapだけ覚えておけば何でも書ける気がします。

flatMap.png

今のストリームから全く別のストリームを作れる、というのがflatmapだと思ってます。
例えば以下のようにStringデータ一つに対してArrayを返すこともできます。


Observable.just("1")
          .flatMap{item -> Observable.fromArray(arrayOf(item.toInt(), item.toInt() + 1 ))}

流れてきたデータを元にAPIを実行してレスポンス情報が流れるストリームを作ることもできますし、割と万能感がありますので最初はこちらを使って書いていきつつ、より綺麗にかけるAPIを探して行くのがいいのではないかと思います。

代表的なものを以下に記載します。

API名 概要
map 流れているデータを1:1で変換したストリームを生成する
flatmap 流れているデータを元に何かしらに変換したストリームを生成する
filter 条件に合うデータだけ流れるストリームを生成する

次の話

【3.実践編】に続く。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5