Androidで非同期通信を使おうとして、AsyncTaskLoaderを使うと、コードが長くなり、考慮する点も多いので、Rxhjavaを使ってみました。
今ではこちらの方が主流な理由がわかりました。
####①ライブラリの追加
下記ライブラリを追加しました。
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の作成です。
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で通信を行い、取得したデータを使って、その後処理を行うという流れです。
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()を実行します。
1点注意しないといけないのが、baseURLは末尾に/がないとエラーが発生します。
.subscribeOn(Schedulers.newThread())
で新しい別スレッドで実行することを定義し、observeOn(AndroidSchedulers.mainThread())
で取得結果をメインスレッドで受け取るようにしています。subscribeの前半の{}は成功したときの処理、こうはんはエラーが発生したときの処理になっています。AsyncTaskLoaderを継承させてみたいなややこしい処理はいらず、エラー処理も単純なので、記述も減ります。
最後に使ってみて見やすくて、便利でした。また、処理のチェーンなども手軽にできそうで何より、コード量が減るのがいいですね。
####参照
Connect to an API With Retrofit, RxJava 2, and Kotlin
Android working with Retrofit and RxJava in Kotlin