RxAndroid-点击可重试 [英] RxAndroid - retry observable on click

查看:117
本文介绍了RxAndroid-点击可重试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆