Retrofitで実装したAPIにRxJavaを混ぜてみる
前回はRetrofitでグルメAPIを叩く処理を実装しました。
今回はそれにRxJavaを加えてみたいと思います。正直API1つだけで単純にデータを取得してるだけの処理だとあまり恩恵を感じないかもしれません。
あるAPIを叩いて戻り値を受け取ってその戻り値を元にまた別のAPIを叩くとかPromise的な処理をしたいときには便利そう。
app/build.gradle
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta3' compile 'io.reactivex:rxandroid:1.0.1'
まずは定義。次に、MainActivity部分。
Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://webservice.recruit.co.jp") .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build();
RxJavaを使用するときは上のように定義しないとだめらしいです。
Observable<GourmetData> observable = service.getGourmetData(Environment.API_KEY, "Z012", "json"); observable .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .map(new Func1<GourmetData, List<Shop>>() { @Override public List<Shop> call(GourmetData gourmetData) { return gourmetData.results.getShop(); } }) .subscribe(new Subscriber<List<Shop>>() { @Override public void onCompleted() { System.out.println("Completed!"); } @Override public void onError(Throwable e) { System.out.println("Error:" + e.getMessage()); } @Override public void onNext(List<Shop> shops) { StringBuilder builder = new StringBuilder(); for (Shop shop : shops) { builder.append(shop.getName() + "\n"); } ((TextView) findViewById(R.id.textview)).setText(new String(builder)); } });
後はAPIのコール部分です。CallをObservableに変更して、通信は非同期・TextViewへの反映はUIスレッドで行おうとするとこんな感じの記述になりました。RxJavaは触り始めたばっかでまだまだ理解できていません・・・。精進せねば