API class using Retrofit
class interface TestApi { @GET("/path/abc/xyz") fun get(): Single }
UseCase class
fun getResult(): Single { return testApi.get() .map{ response -> val type = response.type when(type){ null -> throw Exception() else -> response } } .retryWhen{ throwableHandler -> throwableHandler.flatMap { when(it) { is Exception() -> Flowable.error(it) else -> Flowable.timer(3,TimeUnit.SECONDS) } } } .timeout(60, TimeUnit.SECONDS) }
MainClass.kt
usecase.getResult() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeBy(onError = {Log.d(TAG,"Error")}, onSuccess = {Log.d(TAG,"Next")})
When app run :
If api return NULL, retryWhen() will be invoked then api is called again.
Event not timeout reached and api return Not NUL result -> onSuccess is called. This is correctly processing of retryWhen() operator in rxJava.
My Problem:
If I write some test method (to pretend API Retrofit) in MainClass.kt looks like below:
private fun testPretend(): Single<Animal> {
return Single.just(Animal)
}
MainClass.kt looks like:
testPretend()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeBy(onError = {Log.d(TAG,"Error")},
onSuccess = {Log.d(TAG,"Next")})
So event retryWhen is invoked , testPretend() method is not called again.
What is the problem here?
And what is difference between Single return by testPrerend() and Retrofit API ?
The method testPretend()
is not called again because the observable that it returned is what is being resubscribed to. If you want the method to be invoked again upon resubscription, you will need to do something like this:
Single.defer( () => testPretend() )
...
.retryWhen( ... )
...;
This will invoke testPretend()
upon resubscription.