Android RxJava:尝试将错误传播到Observer.onError时出错

Android RxJava:尝试将错误传播到Observer.onError时出错,android,exception,rx-java,onerror,rx-android,Android,Exception,Rx Java,Onerror,Rx Android,我在Rx库中遇到一个IllegalStateException错误,不知道问题的根源在哪里,不管是RxJava还是我可能做得不正确 当证书固定(发生在所有服务器请求上)但似乎指向会话超时或注销并返回时,会发生致命的崩溃。复制步骤(大约25%的时间发生)如下:登录,打开列表项-滚动到最后-注销-登录-打开应用程序-关闭应用程序->崩溃 有人知道如何防止这种情况吗?我在这里发现了类似的问题 发生的情况是,Subscriber中的onError实现正在抛出一个未经检查的异常,该异常与可观察合约不符,这

我在Rx库中遇到一个IllegalStateException错误,不知道问题的根源在哪里,不管是RxJava还是我可能做得不正确

当证书固定(发生在所有服务器请求上)但似乎指向会话超时或注销并返回时,会发生致命的崩溃。复制步骤(大约25%的时间发生)如下:登录,打开列表项-滚动到最后-注销-登录-打开应用程序-关闭应用程序->崩溃

有人知道如何防止这种情况吗?我在这里发现了类似的问题


发生的情况是,
Subscriber
中的
onError
实现正在抛出一个未经检查的异常,该异常与可观察合约不符,这将中止可观察处理,并在
observeOn
调度程序中抛出一个
OnErrorFailedException

您可能正在从
onError
回调传递活动上下文。当我试图显示一个AlertDialog(传递给它一个特定的活动上下文)并在对话框出现之前按下后退按钮时,我就遇到了这种情况。我的建议是不要以这种方式传递活动上下文。

如果要在OneError中更新UI,请尝试:

api.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber(){....})

我就是这样解决这个问题的:

public abstract class MyNetworkSubscriber<T> extends Subscriber<T> {

@Override
public void onCompleted() {}

@Override
public void onError(Throwable e) {
    if (e instanceof HttpException) {
        ResponseBody responseBody = ((HttpException) e).response().errorBody();
        try {
            if (responseBody != null) {
                MyError error = new Gson().fromJson(responseBody.string(), MyError.class);
                onErrorCode(error);
            }
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    } else {
        e.printStackTrace();
    }
}

public void onErrorCode(MyError error){};
}
公共抽象类MyNetworkSubscriber扩展了Subscriber{
@凌驾
已完成的公共void(){}
@凌驾
公共无效申报人(可丢弃的e){
if(HttpException的实例){
ResponseBody ResponseBody=((HttpException)e).response().errorBody();
试一试{
if(responseBody!=null){
MyError error=new Gson().fromJson(responseBody.string(),MyError.class);
错误代码(错误);
}
}捕获(IOE1异常){
e1.printStackTrace();
}
}否则{
e、 printStackTrace();
}
}
公共错误代码(MyError error){};
}
出于某种原因,OkHttp迫使我抓住一个错误,所以我就这么做了。如果我没有这样做,OkHttp/改装将崩溃,应用程序将关闭

通过提供这种解决方案

  • 您可以选择覆盖您自己的
    onErrorCode
    ,并将更详细的对象作为错误从API返回,但您不必这样做
  • OnError已被覆盖,不再出现疯狂的崩溃
  • 最后但并非最不重要的是,它仍然是通用的,因为

    您还可以强制重写onComplete&onError以使方法抽象

    嗨,斯科特。有可能知道Android版本、RxJava版本、RxAndroid版本吗?您是否正确地处理了所有订阅?io.reactivex:rxandroid:0.24.0 io.reactivex:rxjava:1.0.12
    Android版本5.1
    是的,我正在取消订阅所有订阅,然后将其设置为空。您可以尝试rxandroid 1.0.1吗https://github.com/ReactiveX/RxAndroid/releases/tag/v1.0.1 拜托?谢谢@IvanMorgillo我会的看看这是否还在发生。谢谢这听起来像是一个非常具体的问题case@CarloLópezScutaro是什么导致了你的问题?这发生在我身上。完全相同的情景。你是如何创建这个对话框的?我已经将我的对话框创建抽象为一个util类,因此我需要向它传递一个上下文来创建AlertDialog.ok,但是如果我们需要在调用
    onError
    时创建一个对话框?@Choletski尝试使用
    if(activity!=null&&isAdded()){}
    来包装代码,如果您从片段显示对话框。它应该可以防止这种情况出现非法状态异常。值得指出的是,如果您试图通过在
    onError
    实现中登录来调试它,您可能在logcat中看不到它。您最好使用断点进行调试。这就是我最初没有看到问题的原因。我如何在
    onError()
    回调中跟踪确切的错误,而不是接收此通用堆栈跟踪?如何修复?如何修复?您在onError的实现中接收到一个可丢弃的错误,然后在处理该错误时导致另一个错误。我会修复您的实现,这样它就不会这样做。为了帮助您进行调试,您可以通过使用try-catch包装onError实现来记录抛出的错误。
    public abstract class MyNetworkSubscriber<T> extends Subscriber<T> {
    
    @Override
    public void onCompleted() {}
    
    @Override
    public void onError(Throwable e) {
        if (e instanceof HttpException) {
            ResponseBody responseBody = ((HttpException) e).response().errorBody();
            try {
                if (responseBody != null) {
                    MyError error = new Gson().fromJson(responseBody.string(), MyError.class);
                    onErrorCode(error);
                }
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        } else {
            e.printStackTrace();
        }
    }
    
    public void onErrorCode(MyError error){};
    }