woshidan's blog

あいとゆうきとITと、とっておきの話。

ReactiveAndroidで遊ぶ

現場のコードだとネットワークとかの処理が入ってくるので、その前に単体で触りたいよね、ということで遊びました。UIスレッドの指定の部分以外、RxJavaの範囲かもしれない。

参考:

github.com

kirimin.hatenablog.com

準備

まず、build.gradle

compile 'io.reactivex:rxandroid:1.0.1'
compile 'io.reactivex:rxjava:1.0.15'

を入れてRebuildします。

前知識

なんとなく、

  • Observable = ストリームに値を発信してくるもの
  • Subscribe = 放出されてきた値(ときたまエラー)を受け取って処理をすること
    • Observer(Observableから飛んできた値を受け取って処理する人)

みたいになっていて、

  • observeOnっていうのは、Observerの処理をどこで行うか
  • subscribeOnというのは値を放出する部分の処理をどこで受け持つか

という風に見えます。

とりあえず書いてみる

とりあえずここのお手本に従って書いてみます。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Observable.just("one","two","three","four","five")
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<String>() {
                @Override
                public void call(String s) {
                    Log.d("RxAndroidTestFirst", s);
                }
            });
}
11-08 18:20:21.792      966-966/com.example.woshidan.rxandroidex D/RxAndroidTestFirst﹕ one
11-08 18:20:21.792      966-966/com.example.woshidan.rxandroidex D/RxAndroidTestFirst﹕ two
11-08 18:20:21.792      966-966/com.example.woshidan.rxandroidex D/RxAndroidTestFirst﹕ three
11-08 18:20:21.792      966-966/com.example.woshidan.rxandroidex D/RxAndroidTestFirst﹕ four
11-08 18:20:21.792      966-966/com.example.woshidan.rxandroidex D/RxAndroidTestFirst﹕ five
// 配列の順にログが出てる

Obeserverを書くにあたって

お手本では/* an Observer */とコメントの部分に入ってるAction1<String>という記法がサジェストされたとき、正直よくわからなかったです。 ひとまず、<T>はTで指定されているクラスのオブジェクトを扱うコレクションっぽいですね。

もう少し見てると、Action1というは、Android studioによるとRx.functions中のインタフェースらしいです。

これは、結果を1つだけ受け取る(文字列の形で)という意味なのかもしれません。

そう思いながらこちらの記事などを読んでみますと、本当はObserverクラスをがっつり(?)書いて、それを渡す、というところなんでしょう。

Action1Observer<T>クラスのうち、onNext時だけ実装された状態をcall()に書いているような感じみたいですね。

~~Onで指定しているスレッドについて

  • observeOnっていうのは、Observerの処理をどこで行うか
  • subscribeOnというのは値を放出する部分の処理をどこで受け持つか

が若干自信ないです。

なので、Observerの処理として超簡単なUI処理(Toastの表示)を書いて、 observeOn(=subscribeメソッドに渡したObserverに当たるインタフェースの実装やObserverのインスタンスの処理の実行先)にMainThread以外を指定したらどうなるか見てみます。

// コード1. 比較用
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Observable.just("one","two","three","four","five")
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<String>() {
                @Override
                public void call(String s) {
                    Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();;
                }
            });
}
// コード2
.subscribeOn(Schedulers.newThread())
.observeOn(Schedulers.newThread())

コード1

www.gfycat.com

コード2

f:id:woshidan:20151109032154p:plain

たぶん、UIスレッド以外でToastの表示をさせようと指定したつもりの方がエラーでこけているので、これでよさそうです。

とりあえず今日はここまで。今度はボタンのクリックイベントを受け取って、ネットワーク通信で何か取ってきてみたいです。