gpt4 book ai didi

java - RxJava : observeOn, subscribeOn, and doFinally, IO和UI线程切换

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:44:41 29 4
gpt4 key购买 nike

我遇到了一个问题,我的可观察对象在 IO 线程上订阅并在 android 主 (UI) 线程上观察,但 doFinally 运算符在 IO 线程上运行,它需要在 UI 线程上运行。

用例几乎和这个medium article一模一样.

我基本上想在订阅 Observable 时显示一个 ProgressBar,并在 Observable 终止或完成时隐藏 ProgressBar

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

任何人都可以帮我将 doFinally 操作移回具有循环程序的 UI 线程吗?还是我遗漏了一些其他信息?

编辑用例工作流程是:

->启动 Activity

->初始化

->执行可观察流

->开始新的Activity并完成当前的Activity

->新 Activity

->开始原始 Activity 并完成

->重复初始化

非常感谢。

详细信息:

  • RxJava 2.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());
}
}
}
);

堆栈跟踪:

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)

最佳答案

出现此问题是因为我没有在 Activity 完成/销毁时处理订阅。

现在,每个 Activity/ View 都会在停止或销毁时通知演示者,并且演示者会处理订阅。

这似乎解决了我的问题。

 @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();
}
}

关于java - RxJava : observeOn, subscribeOn, and doFinally, IO和UI线程切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43682611/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com