RxJava:尝试将错误传播到 Observer.onError 时发生错误
RxJava: Error occurred when trying to propagate error to Observer.onError
我在 Rx 库中遇到 IllegalStateException 错误,我不知道问题的确切根源在哪里,是 RxJava 问题还是我做错了什么。
当证书固定(发生在所有服务器请求上)但似乎指向会话超时或注销并重新登录时发生致命崩溃。重现步骤(发生大约 25% 的时间)如下:登录,打开列表项 - 一直滚动结束 - 注销 - 重新登录 - 打开应用 - 关闭应用 -> 崩溃!
有人知道如何防止这种情况发生吗?我在这里发现了类似的问题 Observer.onError firing off inconsistently
java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:62)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4867)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: rx.exceptions.OnErrorFailedException: Error occurred when trying to propagate error to Observer.onError
at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:201)
at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:111)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:159)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4867)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: rx.exceptions.CompositeException: 2 exceptions occurred.
at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:201)
at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:111)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:159)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4867)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: rx.exceptions.CompositeException$CompositeExceptionCausalChain: Chain of Causes for CompositeException In Order Received =>
at com.crashlytics.android.SessionDataWriter.getEventAppExecutionExceptionSize(SessionDataWriter.java:597)
at com.crashlytics.android.SessionDataWriter.getEventAppExecutionExceptionSize(SessionDataWriter.java:600)
at com.crashlytics.android.SessionDataWriter.getEventAppExecutionExceptionSize(SessionDataWriter.java:600)
at com.crashlytics.android.SessionDataWriter.getEventAppExecutionSize(SessionDataWriter.java:533)
at com.crashlytics.android.SessionDataWriter.getEventAppSize(SessionDataWriter.java:492)
at com.crashlytics.android.CrashlyticsUncaughtExceptionHandler.writeSessionEvent(CrashlyticsUncaughtExceptionHandler.java:956)
at com.crashlytics.android.CrashlyticsUncaughtExceptionHandler.access0(CrashlyticsUncaughtExceptionHandler.java:56)
at com.crashlytics.android.CrashlyticsUncaughtExceptionHandler.call(CrashlyticsUncaughtExceptionHandler.java:274)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at io.fabric.sdk.android.services.common.ExecutorUtils.onRun(ExecutorUtils.java:58)
at io.fabric.sdk.android.services.common.BackgroundPriorityRunnable.run(BackgroundPriorityRunnable.java:13)
at java.lang.Thread.run(Thread.java:856)
发生的事情是,您在 Subscriber
中的 onError
实现抛出了一个未经检查的异常,这违反了 Observable 契约,这会中止可观察处理并在 OnErrorFailedException
中抛出 observeOn
调度程序。
您可能正在从 onError
回调的某处传递一个 Activity 上下文。当我试图显示一个 AlertDialog - 传递给它一个特定的 Activity 上下文 - 并在该对话框出现之前按下后退按钮时,这发生在我身上。我的建议是不要以这种方式传递 Activity 上下文。
如果你想在 onError 中更新 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){};
}
出于某种原因,OkHttp 强迫我捕获 onError,所以我这样做了。如果我不这样做,OkHttp/Retrofit 将崩溃并且应用程序将关闭。
通过提供此解决方案,
- 您可以选择覆盖您自己的
onErrorCode
并将更详细的对象作为来自您的 API 的错误返回,但您不必这样做。
- OnError 被覆盖,不再疯狂崩溃。
- 最后但同样重要的是,由于
<T>
,它仍然是通用的!
您还可以强制覆盖 onComplete 和 onError 以使方法抽象。
我在 Rx 库中遇到 IllegalStateException 错误,我不知道问题的确切根源在哪里,是 RxJava 问题还是我做错了什么。
当证书固定(发生在所有服务器请求上)但似乎指向会话超时或注销并重新登录时发生致命崩溃。重现步骤(发生大约 25% 的时间)如下:登录,打开列表项 - 一直滚动结束 - 注销 - 重新登录 - 打开应用 - 关闭应用 -> 崩溃!
有人知道如何防止这种情况发生吗?我在这里发现了类似的问题 Observer.onError firing off inconsistently
java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:62)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4867)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: rx.exceptions.OnErrorFailedException: Error occurred when trying to propagate error to Observer.onError
at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:201)
at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:111)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:159)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4867)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: rx.exceptions.CompositeException: 2 exceptions occurred.
at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:201)
at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:111)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:159)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4867)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: rx.exceptions.CompositeException$CompositeExceptionCausalChain: Chain of Causes for CompositeException In Order Received =>
at com.crashlytics.android.SessionDataWriter.getEventAppExecutionExceptionSize(SessionDataWriter.java:597)
at com.crashlytics.android.SessionDataWriter.getEventAppExecutionExceptionSize(SessionDataWriter.java:600)
at com.crashlytics.android.SessionDataWriter.getEventAppExecutionExceptionSize(SessionDataWriter.java:600)
at com.crashlytics.android.SessionDataWriter.getEventAppExecutionSize(SessionDataWriter.java:533)
at com.crashlytics.android.SessionDataWriter.getEventAppSize(SessionDataWriter.java:492)
at com.crashlytics.android.CrashlyticsUncaughtExceptionHandler.writeSessionEvent(CrashlyticsUncaughtExceptionHandler.java:956)
at com.crashlytics.android.CrashlyticsUncaughtExceptionHandler.access0(CrashlyticsUncaughtExceptionHandler.java:56)
at com.crashlytics.android.CrashlyticsUncaughtExceptionHandler.call(CrashlyticsUncaughtExceptionHandler.java:274)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at io.fabric.sdk.android.services.common.ExecutorUtils.onRun(ExecutorUtils.java:58)
at io.fabric.sdk.android.services.common.BackgroundPriorityRunnable.run(BackgroundPriorityRunnable.java:13)
at java.lang.Thread.run(Thread.java:856)
发生的事情是,您在 Subscriber
中的 onError
实现抛出了一个未经检查的异常,这违反了 Observable 契约,这会中止可观察处理并在 OnErrorFailedException
中抛出 observeOn
调度程序。
您可能正在从 onError
回调的某处传递一个 Activity 上下文。当我试图显示一个 AlertDialog - 传递给它一个特定的 Activity 上下文 - 并在该对话框出现之前按下后退按钮时,这发生在我身上。我的建议是不要以这种方式传递 Activity 上下文。
如果你想在 onError 中更新 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){};
}
出于某种原因,OkHttp 强迫我捕获 onError,所以我这样做了。如果我不这样做,OkHttp/Retrofit 将崩溃并且应用程序将关闭。
通过提供此解决方案,
- 您可以选择覆盖您自己的
onErrorCode
并将更详细的对象作为来自您的 API 的错误返回,但您不必这样做。 - OnError 被覆盖,不再疯狂崩溃。
- 最后但同样重要的是,由于
<T>
,它仍然是通用的!
您还可以强制覆盖 onComplete 和 onError 以使方法抽象。