RxJava:observeOn、subscribeOn和dox最后,在IO和UI线程之间切换

RxJava:observeOn、subscribeOn和dox最后,在IO和UI线程之间切换,java,android,rx-java2,Java,Android,Rx Java2,我遇到了一个问题,我的observable在IO线程上订阅,在android主(UI)线程上观察,但doFinally操作符在IO线程上运行,需要在UI线程上运行 用例几乎与此完全相同 我主要想在订阅可观察对象时显示ProgressBar,在可观察对象终止或完成时隐藏ProgressBar 我得到的错误是:java.lang.IllegalStateException:当前线程必须有一个循环器 有人能帮我把doFinally操作移回有活套的UI线程吗?还是我遗漏了其他信息 编辑 用例工作流是:

我遇到了一个问题,我的observable在IO线程上订阅,在android主(UI)线程上观察,但
doFinally
操作符在IO线程上运行,需要在UI线程上运行

用例几乎与此完全相同

我主要想在订阅可观察对象时显示
ProgressBar
,在可观察对象终止或完成时隐藏
ProgressBar

我得到的错误是:java.lang.IllegalStateException:当前线程必须有一个循环器

有人能帮我把
doFinally
操作移回有活套的UI线程吗?还是我遗漏了其他信息

编辑 用例工作流是:

->发射活动

->初始化

->执行可观察流

->启动新活动并完成当前活动

->新活动

->开始原始活动并完成

->重复初始化

多谢各位

详情:

  • rxjava2.0.7
  • RxAndroid 2.0.1
  • Android sdk最小14和目标25
示例代码

listUseCase.execute(null)
            .doOnSubscribe(new Consumer<Disposable>() {
                @Override
                public void accept(@NonNull Disposable disposable) throws Exception {
                    getView().showLoading(true);
                }
            })
            .doFinally(new Action() {
                @Override
                public void run() throws Exception {
                    getView().showLoading(false);
                }
            })
            .subscribeOn(schedulerProvider.io())
            .observeOn(schedulerProvider.main())
            .subscribe(
                    new Consumer<List<AccountEntity>>() {
                        @Override
                        public void accept(@NonNull List<AccountEntity> accountEntities) throws Exception {
                            getView().setAccounts(accountEntities);
                        }
                    },
                    new Consumer<Throwable>() {
                        @Override
                        public void accept(@NonNull Throwable throwable) throws Exception {
                            if (isViewAttached()) {
                                getView().showError(throwable.getMessage());
                            }
                        }
                    }
            );
listUseCase.execute(空)
.doOnSubscribe(新消费者(){
@凌驾
public void accept(@NonNull一次性)引发异常{
getView().showLoading(true);
}
})
.doFinally(新操作(){
@凌驾
public void run()引发异常{
getView().showLoading(false);
}
})
.subscribeOn(schedulerProvider.io())
.observeOn(schedulerProvider.main())
.订阅(
新消费者(){
@凌驾
public void accept(@NonNull List accountEntities)引发异常{
getView().setAccounts(accountEntities);
}
},
新消费者(){
@凌驾
public void accept(@NonNull Throwable Throwable)引发异常{
如果(isViewAttached()){
getView().batherRor(throwable.getMessage());
}
}
}
);
堆栈跟踪:

FATAL EXCEPTION: RxCachedThreadScheduler-1
  Process: com.example.android.demo.customerfirst.alpha, PID: 16685
  java.lang.IllegalStateException: The current thread must have a looper!
      at android.view.Choreographer$1.initialValue(Choreographer.java:96)
      at android.view.Choreographer$1.initialValue(Choreographer.java:91)
      at java.lang.ThreadLocal$Values.getAfterMiss(ThreadLocal.java:430)
      at java.lang.ThreadLocal.get(ThreadLocal.java:65)
      at android.view.Choreographer.getInstance(Choreographer.java:192)
      at android.animation.ValueAnimator$AnimationHandler.<init>(ValueAnimator.java:600)
      at android.animation.ValueAnimator$AnimationHandler.<init>(ValueAnimator.java:575)
      at android.animation.ValueAnimator.getOrCreateAnimationHandler(ValueAnimator.java:1366)
      at android.animation.ValueAnimator.end(ValueAnimator.java:998)
      at android.graphics.drawable.AnimatedVectorDrawable.stop(AnimatedVectorDrawable.java:439)
      at android.widget.ProgressBar.stopAnimation(ProgressBar.java:1523)
      at android.widget.ProgressBar.onVisibilityChanged(ProgressBar.java:1583)
      at android.view.View.dispatchVisibilityChanged(View.java:8643)
      at android.view.View.setFlags(View.java:9686)
      at android.view.View.setVisibility(View.java:6663)
      at android.widget.ProgressBar.setVisibility(ProgressBar.java:1563)
      at com.example.android.demo.customerfirst.featuresstore.list.ProductListActivity.showLoading(ProductListActivity.java:121)
      at com.example.android.demo.customerfirst.featuresstore.list.ProductListPresenterMediator$3.run(ProductListPresenterMediator.java:56)
      at io.reactivex.internal.operators.observable.ObservableDoFinally$DoFinallyObserver.runFinally(ObservableDoFinally.java:144)
      at io.reactivex.internal.operators.observable.ObservableDoFinally$DoFinallyObserver.onComplete(ObservableDoFinally.java:94)
      at io.reactivex.internal.observers.DisposableLambdaObserver.onComplete(DisposableLambdaObserver.java:73)
      at io.reactivex.internal.observers.DeferredScalarDisposable.complete(DeferredScalarDisposable.java:84)
      at io.reactivex.internal.operators.observable.ObservableFromCallable.subscribeActual(ObservableFromCallable.java:52)
      at io.reactivex.Observable.subscribe(Observable.java:10700)
      at io.reactivex.internal.operators.observable.ObservableDoOnLifecycle.subscribeActual(ObservableDoOnLifecycle.java:33)
      at io.reactivex.Observable.subscribe(Observable.java:10700)
      at io.reactivex.internal.operators.observable.ObservableDoFinally.subscribeActual(ObservableDoFinally.java:45)
      at io.reactivex.Observable.subscribe(Observable.java:10700)
      at io.reactivex.internal.operators.observable.ObservableSubscribeOn$1.run(ObservableSubscribeOn.java:39)
      at io.reactivex.Scheduler$1.run(Scheduler.java:138)
      at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:59)
      at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:51)
      at java.util.concurrent.FutureTask.run(FutureTask.java:237)
      at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(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)
致命异常:RxCachedThreadScheduler-1
进程:com.example.android.demo.customerfirst.alpha,PID:16685
java.lang.IllegalStateException:当前线程必须有一个循环器!
位于android.view.Choreographer$1.initialValue(Choreographer.java:96)
位于android.view.Choreographer$1.initialValue(Choreographer.java:91)
位于java.lang.ThreadLocal$Values.getAfterMiss(ThreadLocal.java:430)
位于java.lang.ThreadLocal.get(ThreadLocal.java:65)
位于android.view.Choreographer.getInstance(Choreographer.java:192)
在android.animation.ValueAnimator$AnimationHandler。(ValueAnimator.java:600)
在android.animation.ValueAnimator$AnimationHandler。(ValueAnimator.java:575)
位于android.animation.ValueAnimator.getOrCreateAnimationHandler(ValueAnimator.java:1366)
位于android.animation.ValueAnimator.end(ValueAnimator.java:998)
在android.graphics.drawable.AnimatedVectorDrawable.stop(AnimatedVectorDrawable.java:439)
在android.widget.ProgressBar.stopAnimation(ProgressBar.java:1523)中
在android.widget.ProgressBar.onVisibilityChanged(ProgressBar.java:1583)
在android.view.view.dispatchVisibilityChanged(view.java:8643)
位于android.view.view.setFlags(view.java:9686)
在android.view.view.setVisibility上(view.java:6663)
位于android.widget.ProgressBar.setVisibility(ProgressBar.java:1563)
在com.example.android.demo.customerfirst.featuresstore.list.ProductListActivity.showLoading(ProductListActivity.java:121)上
在com.example.android.demo.customerfirst.featuresstore.list.ProductListPresenterMediator$3.run(ProductListPresenterMediator.java:56)
在io.reactivex.internal.operators.observable.observabledodenally$DoFinallyObserver.runFinally(observabledodenally.java:144)
在io.reactivex.internal.operators.observable.ObservabledFinallyObserver.onComplete中(ObservabledFinallyObserver.java:94)
位于io.reactivex.internal.observer.DisposableLambdaObserver.onComplete(DisposableLambdaObserver.java:73)
在io.reactivex.internal.observators.DeferredScalarDisposable.complete(DeferredScalarDisposable.java:84)
在io.reactivex.internal.operators.observable.ObservableFromCallable.subscribeActual(ObservableFromCallable.java:52)
在io.reactivex.Observable.subscribe(Observable.java:10700)
在io.reactivex.internal.operators.observable.ObservedOnLiFeCycle.subscribeActual(ObservedOnLiFeCycle.java:33)
在io.reactivex.Observable.subscribe(Observable.java:10700)
在io.reactivex.internal.operators.observable.observabledtofinally.subscribeActual(observabledtofinally.java:45)
在io.reactivex.Observable.subscribe(Observable.java:10700)
在io.reactivex.internal.operators.observable.observablesubscribeeon$1.run(observablesubscribeen.java:39)
在io.reactivex.Scheduler$1.run(Scheduler.java:138)
在io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:59)
位于io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:51)
位于java.util.concurrent.FutureTask.run(FutureTask.java:237)
位于java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
位于java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
位于java.util.concurrent.ThreadPoolExecutor.runWorker(线程池
listUseCase.execute(null)
            .subscribeOn(schedulerProvider.io()) // Move subscribe on here
            .observeOn(schedulerProvider.main()) // Change threads here
            .doOnSubscribe(new Consumer<Disposable>() {
                @Override
                public void accept(@NonNull Disposable disposable) throws Exception {
                    getView().showLoading(true); // This should be on the main thread also
                }
            })
            .doFinally(new Action() {
                @Override
                public void run() throws Exception {
                    getView().showLoading(false);
                }
            })

            .subscribe(
                    new Consumer<List<AccountEntity>>() {
                        @Override
                        public void accept(@NonNull List<AccountEntity> accountEntities) throws Exception {
                            getView().setAccounts(accountEntities);
                        }
                    },
                    new Consumer<Throwable>() {
                        @Override
                        public void accept(@NonNull Throwable throwable) throws Exception {
                            if (isViewAttached()) {
                                getView().showError(throwable.getMessage());
                            }
                        }
                    }
            );
 @Override
public void initialize() {
    if (!isViewAttached()) {
        throw new ViewNotAttachedException();
    }
    disposable = listUseCase.execute(null)
            .subscribeOn(schedulerProvider.io()) // Move subscribe on here
            .observeOn(schedulerProvider.main()) // Change threads here
            .doOnSubscribe(new Consumer<Disposable>() {
                @Override
                public void accept(@NonNull Disposable disposable) throws Exception {
                    getView().showLoading(true); // This should be on the main thread also
                }
            })
            .doFinally(new Action() {
                @Override
                public void run() throws Exception {
                    getView().showLoading(false);
                }
            })
            .subscribe(
                    new Consumer<List<AccountEntity>>() {
                        @Override
                        public void accept(@NonNull List<AccountEntity> accountEntities) throws Exception {
                            getView().setAccounts(accountEntities);
                        }
                    },
                    new Consumer<Throwable>() {
                        @Override
                        public void accept(@NonNull Throwable throwable) throws Exception {
                            if (isViewAttached()) {
                                getView().showError(throwable.getMessage());
                            }
                        }
                    }
            );
}

@Override
public void dispose() {
    if (disposable != null) {
        disposable.dispose();
    }
}