再次开始 Retrofit 调用,从 RXJava 中的 onError 回调再次订阅 Observable

Starting again a Retrofit call subscribing the Observable again from onError Callback in RXJava

当 Retrofit Call 不成功时(例如因为没有 Internet),将按预期调用 RXJava 回调 onError,其中我有一个 Snackbar 和一个 setAction() 监听器用直观的字符串 "Retry" 表示,我应该在其中传递命令以再次启动网络调用。 我可以在内部调用它 NameActivity() 的地方重新启动 class,但是我可以在 Snackbar 侦听器内部传递这个看起来 terrible.Which 命令以重新启动下面的代码?

 MyViewModel!!.getPost("132")
            ?.subscribeOn(schedulerProvider!!.io())
            ?.observeOn(schedulerProvider!!.ui())
            ?.doOnNext {
                run {
                    spinner.setVisibility(View.VISIBLE)
                }
            }

            ?.subscribe(object : FlowableSubscriber<List<Post>> {
                override fun onError(t: Throwable?) {
                    spinner.setVisibility(View.GONE)

                    spinner.visibility
                    Snackbar.make(view.findViewById(R.id.linearLayout), "Check Internet Connection!", Snackbar.LENGTH_INDEFINITE)
                            .setAction("Retry", {})//HERE THE COMMAND SHOULD PASS
                            .show();

                }

                override fun onComplete() {
                    Log.d("TAG", "onComplete: ")
                }

                override fun onSubscribe(s: Subscription) {
                    s.request(Long.MAX_VALUE);

                }

                override fun onNext(posts: List<Post>?) {
                    spinner.setVisibility(View.GONE)

                    posts?.let { viewAdapter.setTitleData(it) }

                }
            })
}

如果你想在调用失败时立即显示snackbar,你必须再次调用订阅。您可以按如下方式重构您的代码:

  1. 将您的 Rx 代码放在一个方法中。例如doNetworkCall().
  2. 创建一个单独的方法来处理您的错误。例如handleError(t: Throwable)
  3. 在该方法中,您可以使 Snackbar 出现,并在用户点击重试操作后调用 doNetworkCall() 方法。

示例:

fun doNetworkCall() {
    MyViewModel!!.getPost("132")
            ?.subscribeOn(schedulerProvider!!.io())
            ?.observeOn(schedulerProvider!!.ui())
            // The rest of the code here was removed for brevity.
             ?.subscribe(object : FlowableSubscriber<List<Post>> {
                override fun onError(t: Throwable?) {
                    spinner.setVisibility(View.GONE)
                    spinner.visibility

                    handleError(t) // Call the method here.
                }
            // The rest of the code here was removed for brevity.
}

fun handleError(t: Throwable?) {
    // Here you can also check the type of the error, and perhaps even change the snackbar action depending on it.
    Snackbar.make(view.findViewById(R.id.linearLayout), "Check Internet Connection!", Snackbar.LENGTH_INDEFINITE)
            .setAction("Retry", doNetworkCall()) // Set the retry action to call the doNetworkCall() method again.
            .show()
}

您还可以在向用户提示任何内容之前使用自动重试。这可以通过使用 Rx retry operator 来实现。如果您的网络呼叫失败,它将自动重新订阅给定的尝试次数。

如 ReactiveX 文档所述:

  • One variant of retry takes no parameters. It will continue to resubscribe to and mirror the source Observable no matter how many onError notifications it receives.

  • Another variant of retry takes a single parameter: a count of the number of times it should try to resubscribe to the source Observable when it encounters errors. If this count is exceeded, retry will not attempt to resubscribe again and will instead pass the latest onError notification to its observers.

  • A third variant of retry takes a predicate function as a parameter. You write this function to accept two arguments: an Integer count of how many retries have taken place thusfar, and a Throwable indicating the error that caused the onError notification. This function returns a Boolean to indicate whether or not retry should resubscribe to and mirror the source Observable. If it does not, then retry passes the latest onError notification to its observers.