RxJava - 捕捉消费者异常

RxJava - Catching Consumer Exception

我目前正在尝试为我的 Android 应用程序中的网络处理找到更好的解决方案。目前,我正在使用 RxJava,还有一些 Consumer 类.

消费者

public interface Consumer<T> {
    /**
     * Consume the given value.
     * @param t the value
     * @throws Exception on error
     */
    void accept(T t) throws Exception;
}

网络消费者

abstract class NetworkConsumer<T> : Consumer<NetworkResponse<T>> {

    override fun accept(response: NetworkResponse<T>) {
        if (response.isSuccessful()) {
            onSuccess(response.data)
        } else {
            onFailure()
        }
    }

    // other functions such as onSuccess and onFailure
}

使用 NetworkConsumer

UserService.login(email, password)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(object : NetworkConsumer<LoginResponse>() {
                        override fun onSuccess(response: LoginResponse) {
                            super.onSuccess(response)
                            startMainActivity()
                        }

                        override fun onFailure() {
                            Toast.makeText(this@LoginActivity, "Could not login.", Toast.SHORT_LENGTH).show()
                        }

                    })

现在,这在大多数正常情况下都能正常工作,例如登录成功或 404 错误。但是,如果存在 Exception,例如 HttpExceptionSocketTimeOutException,则不会调用 onFailure()

我找到的解决这个问题的唯一方法是使用另一个 Consumer 来处理 RxJavaPlugins 中的 Exceptions

RxJavaPlugins.setErrorHandler(new NetworkErrorConsumer());

NetworkErrorConsumer

class NetworkErrorConsumer : Consumer<Throwable> {
    override fun accept(exception: Throwable) {
        // ...
    }
}

问题是要通知 UI 出现错误,我需要使用事件总线将消息发送回 Activity。

是否有更好的解决方案可以让我 catch 我的 NetworkConsumer 中的那些 Exceptions

我非常想要一个解决方案,它允许我在调用 login 时使用 Lambda 样式,而不是创建另一个对象。

谢谢!

subscribe() 方法的一个版本接受 Observer,您可以创建一个具有基本异常处理的基本方法:

abstract class NetworkObserver<T> : Observer<NetworkResponse<T>> {

    override fun onError(exception: Throwable) {
        //your base exception handling
    }

    override fun onNext(response: NetworkResponse<T>) {
        if (response.isSuccessful()) {
            onSuccess(response.data)
        } else {
            onFailure()
        }
    }

    override fun onComplete() {}

    override fun onSubscribe(d: Disposable) {}

    //onSucess & onFailure functions

}

然后使用此 class 的实现作为您的登录逻辑:

UserService.login(email, password)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object : NetworkObserver<LoginResponse>() {
                    override fun onNext(response: LoginResponse) {
                        super.onNext(response)
                        //additional logic
                    }

                    override fun onSuccess(response: LoginResponse) {
                        super.onSuccess(response)
                        startMainActivity()
                    }

                    override fun onFailure() {
                        Toast.makeText(this@LoginActivity, "Could not login.", Toast.SHORT_LENGTH).show()
                    }

                    //you can override onError() method if
                    //you need additional exception handling logic
                })

但是使用这种方法你将无法使用 Lamda 风格