代码之家  ›  专栏  ›  技术社区  ›  advice

RxJava-捕获使用者异常

  •  1
  • advice  · 技术社区  · 8 年前

    我目前正试图在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 ,例如 HttpException 或a SocketTimeOutException 这个 onFailure() 不会调用。

    我找到的解决这个问题的唯一方法是使用另一个 消费者 处理 Exceptions 在RxJavaPlugins中。

    RxJavaPlugins.setErrorHandler(new NetworkErrorConsumer());
    

    网络错误消费者

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

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

    有没有更好的解决方案 catch 那些 例外情况 在我的 NetworkConsumer ?

    我真的希望有一个解决方案,允许我在调用时使用Lambda样式 login ,而不是创建另一个对象。

    谢谢

    1 回复  |  直到 8 年前
        1
  •  1
  •   y.allam    8 年前

    有一个版本的 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
    
    }
    

    然后将此类的实现用于登录逻辑:

    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样式