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

时间:2018-08-29 17:05:58

标签: android rx-java retrofit2 rx-java2 onerror

如果翻新呼叫未成功(例如,因为没有Internet),将按预期方式调用RXJava回调onError,其中我有一个Snackbar和一个setAction()侦听器,直观的字符串“ Retry”,我应该在其中传递命令以再次启动网络调用。 我可以在内部调用NameActivity()的地方重新启动类,但这看起来很糟糕。我可以在Snackbar侦听器内部传递哪个命令来重新启动下面的代码?

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

                }
            })
}

1 个答案:

答案 0 :(得分:1)

如果您想在呼叫失败时立即显示小吃栏,则必须再次呼叫订阅。您可以按以下方式重构代码:

  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文档所述:

  
      
  • 重试的一种变体无需参数。它将继续   重新订阅并镜像源可观察到的无论有多少   收到的onError通知。

  •   
  • 重试的另一个变体采用单个参数:   它应该尝试重新订阅源的次数   当遇到错误时。如果超过此计数,将不会重试   尝试再次重新订阅,而是传递最新的onError   通知观察者。

  •   
  • 重试的第三个变种以谓词函数作为参数。   您编写此函数以接受两个参数:的整数计数   迄今为止已进行了多少次重试,并且出现了Throwable指示   导致onError通知的错误。该函数返回   一个布尔值,指示是否应重试,并且   镜像源Observable。如果不是,则重试通过   最新的onError通知其观察者。

  •