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は末尾に/
が必要になります。
最後に使ってみて見やすくて、便利でした。また、処理のチェーンなども手軽にできそうで何より、コード量が減るのがいいですね。