41

我在 Rx 库中收到 IllegalStateException 错误,并且不知道问题的根源在哪里,无论是 RxJava 还是我可能做错了什么。

当证书固定(发生在所有服务器请求上)时发生致命崩溃,但似乎指向会话超时或注销并重新登录。重现步骤(大约发生 25% 的时间)如下:登录,打开列表项 - 滚动一路结束-注销-重新登录-打开应用-关闭应用->崩溃!

有人对如何防止这种情况有任何想法吗?我在这里发现了一个类似的问题Observer.onError 不一致地触发

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$2.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$2.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.access$200(CrashlyticsUncaughtExceptionHandler.java:56)
   at com.crashlytics.android.CrashlyticsUncaughtExceptionHandler$7.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$1$1.onRun(ExecutorUtils.java:58)
   at io.fabric.sdk.android.services.common.BackgroundPriorityRunnable.run(BackgroundPriorityRunnable.java:13)
   at java.lang.Thread.run(Thread.java:856)
4

4 回答 4

52

正在发生的事情是您onError在 a 中的实现抛出了一个未经检查的异常,该异常违反了 Observable 合同,这会中止在调度程序中Subscriber抛出 an 的可观察处理。OnErrorFailedExceptionobserveOn

于 2015-08-17T01:31:30.540 回答
14

您可能正在从onError回调的某个地方传递一个 Activity 上下文。当我尝试显示 AlertDialog 时发生这种情况 - 将特定的 Activity 上下文传递给它 - 并在该对话框出现之前按下后退按钮。我的建议是不要以这种方式传递 Activity 上下文。

于 2015-09-11T19:49:44.693 回答
2

这就是我解决问题的方法:

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 将崩溃,应用程序将关闭。

通过提供这个解决方案,

  1. 您可以选择覆盖您自己的onErrorCode并获取更详细的对象作为来自您的 API 的错误,但您不必这样做。
  2. OnError 被覆盖,不再有疯狂的崩溃。
  3. 最后但并非最不重要的是,它仍然是通用的,因为<T>

您还可以强制覆盖 onComplete 和 onError 以使方法抽象。

于 2017-12-26T09:20:15.293 回答
0

如果您想在 onError 中更新 UI,请尝试:

api.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber(){....})
于 2017-03-17T03:09:52.680 回答