Scheduler.Worker 线程上抛出异常。添加 `onError` 处理

Exception thrown on Scheduler.Worker thread. Add `onError` handling

我正在尝试一些代码,这是我得到的异常:

Process: in.ddas.pretense, PID: 8249
java.lang.IllegalStateException: Exception thrown on Scheduler.Worker thread. Add `onError` handling.
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:60)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(ScheduledThreadPoolExecutor.java:152)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:818)
 Caused by: rx.exceptions.OnErrorNotImplementedException: Can't create handler inside thread that has not called Looper.prepare()
    at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:386)
    at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:383)
    at rx.internal.util.ActionSubscriber.onError(ActionSubscriber.java:44)
    at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:157)
    at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:120)
    at rx.exceptions.Exceptions.throwOrReport(Exceptions.java:204)
    at rx.observers.SafeSubscriber.onNext(SafeSubscriber.java:144)
    at rx.internal.operators.OperatorSubscribeOn.onNext(OperatorSubscribeOn.java:53)
    at rx.internal.operators.OperatorTake.onNext(OperatorTake.java:77)
    at rx.internal.operators.OnSubscribeTimerPeriodically.call(OnSubscribeTimerPeriodically.java:52)
    at rx.Scheduler$Worker.call(Scheduler.java:134)
    at rx.internal.schedulers.EventLoopsScheduler$EventLoopWorker.call(EventLoopsScheduler.java:187)
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(ScheduledThreadPoolExecutor.java:152) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
    at java.lang.Thread.run(Thread.java:818) 
 Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    at android.os.Handler.<init>(Handler.java:200)
    at android.os.Handler.<init>(Handler.java:114)
    at in.ddas.pretense.GoogleCloudActivity.PredictionEngine(GoogleCloudActivity.java:198)
    at in.ddas.pretense.GoogleCloudActivity.lambda$onClick[=11=](GoogleCloudActivity.java:176)
    at in.ddas.pretense.GoogleCloudActivity$$Lambda.call(Unknown Source)
    at rx.internal.util.ActionSubscriber.onNext(ActionSubscriber.java:39)
    at rx.observers.SafeSubscriber.onNext(SafeSubscriber.java:139)
    at rx.internal.operators.OperatorSubscribeOn.onNext(OperatorSubscribeOn.java:53) 
    at rx.internal.operators.OperatorTake.onNext(OperatorTake.java:77) 
    at rx.internal.operators.OnSubscribeTimerPeriodically.call(OnSubscribeTimerPeriodically.java:52) 
    at rx.Scheduler$Worker.call(Scheduler.java:134) 
    at rx.internal.schedulers.EventLoopsScheduler$EventLoopWorker.call(EventLoopsScheduler.java:187) 
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(ScheduledThreadPoolExecutor.java:152) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
    at java.lang.Thread.run(Thread.java:818) 

这是相同的代码:

try {
                    kf.initFilter();
                    kg.initFilter();
                    Observable.interval(1, TimeUnit.SECONDS)
                            .take(5)
                            // switch execution into main thread
                            .subscribeOn(AndroidSchedulers.mainThread())
                            .subscribe(t -> {
                                PredictionEngine(1);
                            });
                } catch (Exception e) {
                    e.printStackTrace();
                }

private void PredictionEngine(int delay) throws Exception {

    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            enableStrictMode();
            String val = null;
            try {
                if (tHighPass == 0 && tLowPass == 0 && tKalman == 1) {
                    //Magic
                } else {
                    //Magic
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
            enableStrictMode();
            side_output.append(val + "\n");
            new DropboxTask(side_output, "Result", val).execute();
        }
    }, delay);
}

我基本上是在尝试循环 运行 PredictionEngine(int); 函数一定的时间而不阻塞主线程,并有一定的延迟。

我哪里做错了?

谢谢!

Handler 的默认构造函数使用 Looper 实例作为 当前 线程。如果您打算在主线程上使用 运行 代码,并且您的处理程序正在主线程以外的线程中初始化,则需要指定 Looper 供处理程序使用。这可以使用

来完成

Handler h = new Handler(Looper.getMainLooper());