【问题标题】:Starting again a Retrofit call subscribing the Observable again from onError Callback in RXJava再次从 RXJava 中的 onError 回调开始重新订阅 Observable 的 Retrofit 调用
【发布时间】:2018-08-29 17:05:57
【问题描述】:

当改造调用不成功(例如因为没有互联网)时,按预期调用 RXJava 回调onError,其中我有一个Snackbar 和一个setAction() 侦听器,用直观的字符串“重试”指示我应该在哪里传递一个命令来重新开始网络调用。 我可以重新启动我在里面调用它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) }

                }
            })
}

【问题讨论】:

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


    【解决方案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 文档所述:

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

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

    • 第三种重试变体采用谓词函数作为参数。 你编写这个函数来接受两个参数:一个整数计数 到目前为止已经发生了多少次重试,以及一个 Throwable 指示 导致 onError 通知的错误。这个函数返回 一个布尔值,指示是否重试应该重新订阅和 镜像源 Observable。如果没有,则重试通过 向其观察者发出最新的 onError 通知。

    【讨论】:

    • Thanks.Well retry 运算符不适合我的用例,因为无法从 SnackBar 监听器内部调用,所以我想实现你提到的解决方案,但是我该如何实现第 2 点如果 onError 在订阅者回调内部而不是在单独的方法中被调用,换句话说是在 doNetworkCall()you 建议的第一点内
    • 您可以在doNetworkCall() 之外创建一个方法来处理错误,并在Rx 的onError 内调用此方法。
    • 首先,如果我包装我发布的所有代码,我还必须注入视图,以便 fun doNetworkCall(view:View) 因为我有 SnackBarProgressBar 的视图实例,但核心问题是我如何将onError 隔离为一种方法?我正在尝试,但正如预期的那样不起作用,因为 onError 应该订阅一个基本上是所有方法的 Observable doNetworkCall(view:view) 我的意思是 Observable.subscribe(//here are called the 4 rxjava callBacks, and cannot isolate OnError apart!)
    • 令人惊叹的@Mauker 正在工作,非常感谢。回复已接受
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-29
    • 2017-11-05
    • 2019-05-20
    相关资源
    最近更新 更多