It's still just a memo, so I think there are many things that are difficult to understand. I would appreciate it if you could make an edit request as appropriate.
It is a premise that you have a general knowledge of Retrofit and Rx. If you want to know about that, this article will be very helpful. Implement API client quickly with Retrofit and Rx in Kotlin
class MyApiDatasore {
fun <T> createService(service: Class<T>) =
Retrofit.Builder()
.baseUrl("url")
.addConverterFactory(JacksonConverterFactory.create(ObjectMapper()))
.addCallAdapterFactory(RxCallAdapterFactory.create())
.build()
.create(service)!!
}
interface MyApiService {
@Get("hogehoge")
fun fetchHogeHoge()
}
Caller
MyApiDatastore().createService(MyApiService::class.java)
.fetchHogeHoge()
.subscribeOn(Schedulers.newThread()) //Run in a background thread
.observeOn(AndroidSchedulers.mainThread()) //Notify the main thread
.subscribe({
// onSuccess
}) { e ->
// onError
}
It's annoying to write this every time.
...
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
Refer to Articles around here, or refer to the documentation and make your own custom adapter that does the above every time. created.
**
* RxJava adapter for Retrofit.
* Always `subscribeOn(Schedulers.newThread())`
* `observeOn(AndroidSchedulers.mainThread())`
*/
private class RxThreadingCallAdapterFactory : CallAdapter.Factory() {
companion object {
fun create(): CallAdapter.Factory = RxThreadingCallAdapterFactory()
}
//Always run in a new thread
private val original: RxJava2CallAdapterFactory = RxJava2CallAdapterFactory.createWithScheduler(Schedulers.newThread())
override fun get(returnType: Type, annotations: Array<Annotation>, retrofit: Retrofit): CallAdapter<*, *> {
// `original.get() == null` -> Retrofit throws IllegalArgumentException.
return RxCallAdapterWrapper(original.get(returnType, annotations, retrofit)!!)
}
private class RxCallAdapterWrapper<R>(private val wrapped: CallAdapter<R, *>) : CallAdapter<R, Any> {
override fun responseType(): Type = wrapped.responseType()
//Always notify the main thread
override fun adapt(call: Call<R>) = wrapped.adapt(call)
.let {
when (it) {
is Completable -> {
it.observeOn(AndroidSchedulers.mainThread())
}
is Observable<*> -> {
it.observeOn(AndroidSchedulers.mainThread())
}
is Single<*> -> {
it.observeOn(AndroidSchedulers.mainThread())
}
is Flowable<*> -> {
it.observeOn(AndroidSchedulers.mainThread())
}
is Maybe<*> -> {
it.observeOn(AndroidSchedulers.mainThread())
}
else -> errorIfDebug()
}
}!!
}
}
By using the retrofit service as shown below, you can implement the process to run in the background and notify the main thread just by writing .subscribe
every time.
Retrofit.Builder()
.baseUrl("url")
.addConverterFactory(JacksonConverterFactory.create(ObjectMapper()))
.addCallAdapterFactory(RxThreadingCallAdapterFactory.create()) //Use a custom adapter here
.build()
.create(service)!!
Recommended Posts