RxAndroid-点击可重试 [英] RxAndroid - retry observable on click
问题描述
我在我的Android应用中使用rxAndroid和rxKotlin异步处理网络请求.现在,我只想在单击Snackbar按钮后重试失败的网络请求.
I'm using rxAndroid and rxKotlin in my Android app to handle network requests asynchronously. Now I would like to retry a failed network request only after click on Snackbar button.
现在我的代码:
val citiesService = ApiFactory.citiesService
citiesService.cities()
.subscribeOn(Schedulers.newThread()) // fetch List<String>
.flatMap { Observable.from(it) } // convert to sequence of String
.flatMap { city ->
citiesService.coordinates(city) // fetch DoubleArray
.map { City(city, it) } // convert to City(String, DoubleArray)
}
.toList()
.observeOn(AndroidSchedulers.mainThread())
.doOnNext {
listView.setOnItemClickListener { adapterView, view, position, id ->
onItemClick(it[position])
}
}
.map { it.map { it.getName(activity) } }
.subscribe(
{ listAdapter = setupAdapter(it) },
{ showErrorSnackbar() } // handle error
)
fun showErrorSnackbar() {
Snackbar.make(listView, getString(R.string.not_available_msg), Snackbar.LENGTH_INDEFINITE)
.setAction(getString(R.string.snack_retry_btn), {
// retry observable
})
.show()
}
用于改造的城市界面:
interface CitiesService {
@GET("api/v1/cities")
fun cities(): Observable<List<String>>
@GET("api/v1/cities/{city}/coordinates")
fun coordinates(@Path("city") city: String): Observable<DoubleArray>
}
Api工厂:
object ApiFactory {
val citiesService: CitiesService
get() = retrofit.create(CitiesService::class.java)
private val retrofit: Retrofit
get() = Retrofit
.Builder()
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.build()
}
如何以这种方式重新启动可观察的物体?
How can I restart the observable in such way?
推荐答案
我可以建议您使用真正的被动方式,而不是命令式方式.
I can suggest you truly reactive way instead of imperative way.
在subscribe()方法之后立即插入此代码:
Insert this code right after subscribe() method:
.retryWhen(retryHandler ->
retryHandler.flatMap(nothing -> retrySubject.asObservable()))
.subscribe()
更新主题仅是:
@NonNull
private final PublishSubject<Void> retrySubject = PublishSubject.create();
然后在快餐栏上单击调用此方法:
And on snackbar click call this method:
public void update() {
retrySubject.onNext(null);
}
retryWhen方法上方的所有内容都将按原样重做.
Everything above the retryWhen method will be literally redone.
尽管使用这种方法,错误永远不会降到订阅服务器上,但是您可以向retryHandler平面映射添加错误条件,但这是另一回事了.
Though with this approach error will never go down to the subscriber, you can add error conditioning to the retryHandler flat map, but this is another story.
P.S.抱歉,这是带有Retrolambdas的Java代码,但是您可以轻松地将其转换为Kotlin.
P.S. sorry, this was Java code with retrolambdas, but you'll easily convert this to Kotlin.
这篇关于RxAndroid-点击可重试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!