くま's Tech系Blog

基本的には技術で学んだことを書き留めようと思います。雑談もやるかもね!

RxjavaとRetrofitで非同期通信を行う

Androidで非同期通信を使おうとして、AsyncTaskLoaderを使うと、コードが長くなり、考慮する点も多いので、Rxhjavaを使ってみました。 今ではこちらの方が主流な理由がわかりました。

①ライブラリの追加

下記ライブラリを追加しました。

build.gradle

    implementation 'com.squareup.retrofit2:retrofit:2.6.0'
    implementation 'io.reactivex.rxjava2:rxjava:2.2.9'
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
    implementation 'com.squareup.retrofit2:converter-simplexml:2.3.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'

rxJavaのAndroid版のrxAndroidも導入しています。

②Retrofitの実装

今回はxmlをparseする処理を行うので、Retrofitを使います。 タグの名前を指定すれば、値が取得できるので、便利です。 まずは、interfaceの作成です。

RssClient

interface RssClient {

    @GET("{rssPath}")
    fun get(@Path("rssPath") path: String) : Observable<BlogEntity>
}

Rxjavaで使うため、戻り値をObservable型にしています。 また、@Path("rssPath")で実際に使用するときに引数を使うことで、カスタマイズできます。 その時に"{rssPath}"が同じ値になります。 なので、動的にURLを作成したいときに使えます。

次にEntityを作成します。

Entityについては下記の記事を参照してください! Retrofitでxmlの値を取得する

ここまででRetrofitを使えるようになりました。

③Rxjavaの実装

最後に、Rxjavaを使って、非同期処理を行います。 手順としてはRetrofitを作成し、対象のURLで通信を行い、取得したデータを使って、その後処理を行うという流れです。

MainActivity.kt

val retrofit = Retrofit.Builder()
                      .baseUrl(https://×××××××××××/)
                      .client(client)
                      .addConverterFactory(SimpleXmlConverterFactory.create())
                      .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                      .build()

                    val response = retrofit.create(RssClient::class.java).get("rss")

                    // 非同期で記事を取得し、メインスレッドでその後の処理を行う
                    response.observeOn(AndroidSchedulers.mainThread())
                            .subscribeOn(Schedulers.newThread())
                            .subscribe( {
                                //UIの更新など取得したデータを使って処理を行う
                            }, {
                                Log.e("ERROR", it.cause.toString())
                            })

.addConverterFactory(SimpleXmlConverterFactory.create())xmlをパースすることを定義し、.addCallAdapterFactory(RxJava2CallAdapterFactory.create())でRetrofitの処理結果を、RxJava2が利用できる形にしています。 そして、interfaceで定義したget()を実行します。

.subscribeOn(Schedulers.newThread())で新しい別スレッドで実行することを定義し、observeOn(AndroidSchedulers.mainThread())で取得結果をメインスレッドで受け取るようにしています。subscribeの前半の{}は成功したときの処理、こうはんはエラーが発生したときの処理になっています。AsyncTaskLoaderを継承させてみたいなややこしい処理はいらず、エラー処理も単純なので、記述も減ります。 ここで注意しないといけないのが、baseUrlで指定するURLは末尾に/が必要になります。

最後に使ってみて見やすくて、便利でした。また、処理のチェーンなども手軽にできそうで何より、コード量が減るのがいいですね。