重い腰をあげて対応したときのメモです。
RxJava -> RxJava2の変更点
- インターフェースにSingleやMaybeなどが追加されました。
- 詳細はこちらの記事が詳しいです。
対応
準備
- RxJava/RxAndroidのバージョンをあげて、RetrofitのAdapterはJake神が作ったものがあるのでそちらを入れます。
-
https://github.com/JakeWharton/retrofit2-rxjava2-adapter(これは本家が対応したみたいなので役目を終えていました。下のを参照) - https://github.com/square/retrofit/tree/master/retrofit-adapters/rxjava2
-
- RetrofitのインスタンスにセットしているRxJavaのAdapterはJakeのライブラリの
RxJava2CallAdapterFactory
で作ったものをセットします。
インターフェースの変更
- APIのインターフェースでObservableで受けていたところを変更します。
- GETなどレスポンスが返ってくるものは
Single
- POSTなどレスポンスがNoContentのものは
Completable
- 値が流れてくるかどうかの違いはありますが、Subscribeする側は成功したか失敗したかということだけ気にすればよいインターフェースになりました。ちなみにNoContentが返るAPIを
Single
で受けるとonSuccess
にnullは流せないという旨の例外がonError
に流れてきます。
- GETなどレスポンスが返ってくるものは
-
Subscription
は名前が変わってDisposable
になったので、CompositeSubscription
を使っていたところはCompositeDisposable
に変えて、解放するメソッドもunsubscribe
からdispose
に変わります。 - Streamの種類が増えたので、StreamをつなげていたoperatorやdoXXXの種類も増えました。例えばAPIを呼んで返ってきた結果を次のAPIに渡して最終的に
Completable
を返すという場合はこんな感じになります。(コードはkotlinです)
SampleUsecase.kt
fun execute(postData: String): Completable
return retrofitService.getHoge().flatMap { response ->
return@flatMap retrofitService.postFuga(response.id, postData)
}.doOnEvent { response, throwable ->
// 成功 / 失敗にかかわらず実行される処理
}.flatMapCompletable {
// 成功したらレスポンスを処理してCompletableを返す
return@flatMapCompletable Completable.complete()
}.onErrorResumeNext {
// 失敗したらエラーを処理してCompletableを返す
return@onErrorResumeNext Completable.error(RegistrationFailedException())
}
}
- subscribeする側はラムダを使っていればそんなに意識することはないと思いますが、onCompleteには
Action
を渡すけど、SingleにはConsumer<? super T>
を渡すというような違いもあります。
SamplePresenter.kt
fun onClickHogeFuga(value: String) {
disposable?.add(sampleUsecase.execute(value)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
// 成功したときの処理
}, {
// 失敗したときの処理
}))
}
- ちなみに弊社では拡張関数を生やしてこんな感じに書いてます。
SamplePresenter.kt
fun Completable.subscribeAsync(onComplete: () -> Unit, onFailure: (Throwable) -> Unit = {}, onEventFinished: () -> Unit = {}): Disposable {
return subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.doFinally(onEventFinished)
.subscribe(onComplete, onFailure)
}
fun onClickHogeFuga(value: String) {
disposable?.add(sampleUsecase.execute(value).subscribeAsync({
// 成功したときの処理
}, {
// 失敗したときの処理
}))
}
所感など
- Streamの種類が増えたことで、Publishする側は何を流すか考えることが増えた分、Suscribeする側は流れてくるものに合わせることになるので考えることが減りました。個人的には2系の方が素直な実装ができる印象です。