【问题标题】:RxAndroid - retry observable on clickRxAndroid - 点击时重试可观察
【发布时间】:2016-04-23 10:16:23
【问题描述】:

我在我的 Android 应用程序中使用 rxAndroid 和 rxKotlin 来异步处理网络请求。现在我想在点击 Snackbar 按钮后重试失败的网络请求。

我现在的代码:

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()
}

如何以这种方式重新启动 observable?

【问题讨论】:

  • 什么是触发请求?我无法从您的代码中看到这一点。调用cities() 会触发新请求吗?
  • 我在上面添加了更多代码。是的,cities() 触发新请求
  • 然后您可以将整个 citiesService.cities()... 反应链包装到一个新方法中,并从您的 Snackbar 的动作侦听器中调用它。

标签: android rx-java retrofit2 rx-android rx-kotlin


【解决方案1】:

我可以建议您使用真正的被动方式而不是命令方式。

在 subscribe() 方法之后插入这段代码:

.retryWhen(retryHandler -> 
           retryHandler.flatMap(nothing -> retrySubject.asObservable()))
.subscribe()

更新主题只是:

@NonNull
private final PublishSubject<Void> retrySubject = PublishSubject.create();

然后在snackbar上点击调用这个方法:

public void update() {
    retrySubject.onNext(null);
}

retryWhen 方法之上的所有内容都将被重做。

虽然使用这种方法,错误永远不会传递给订阅者,但您可以将错误条件添加到 retryHandler 平面地图,但这是另一回事。

附:抱歉,这是带有 retrolambdas 的 Java 代码,但您可以轻松地将其转换为 Kotlin。

【讨论】:

  • 我也尝试过这种方法,取自android.jlelse.eu/…但是Android Studio显示消息Cannot resolve method asObservable()
  • 得到与 asObservable() 方法相同的错误已从 RxJava2 中删除,但有没有其他方法可以让我在点击时获得相同的功能以重试
猜你喜欢
  • 1970-01-01
  • 2018-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-04
  • 1970-01-01
相关资源
最近更新 更多