RxAndroid:在Schedulers.io()线程上更改UI

我在IO线程上有简单的工作,它正在改变主屏幕壁纸,之后我试图在UI线程上运行一些动画:

AppObservable.bindFragment(this, Observable.just(0)) .observeOn(Schedulers.io()) .subscribe(v -> setWallpaperOnSeparateThread()); private void setWallpaperOnSeparateThread() { WallpaperHelper.setBitmapAsWallpaper(photoViewAttacher.getVisibleRectangleBitmap(), getBaseActivity()); AppObservable.bindFragment(this, Observable.just(0)) .delay(500, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) .subscribe(integer -> loadFinishAnimationAfterSetWallpaper()); } 

但是这种方法导致错误: java.lang.IllegalStateException: Observers must subscribe from the main UI thread, but was Thread[RxCachedThreadScheduler-1,5,main]

我试图将第二个Observable改为:

  AppObservable.bindFragment(this, Observable.just(0)) .delay(2000, TimeUnit.MILLISECONDS) .observeOn(Schedulers.io()) .subscribeOn(AndroidSchedulers.mainThread()) .subscribe(integer -> loadFinishAnimationAfterSetWallpaper()); 

但它没有帮助。

AppObservable.bindFragment(this, Observable.just(0))抛出exception,因为它没有从主线程调用

在主线程中没有调用此代码,因为您在此代码中查看Schedulers.io (参见下文),而不是后者调用AppObservable.bindFragment(this, Observable.just(0))

 AppObservable.bindFragment(this, Observable.just(0)) .observeOn(Schedulers.io()) .subscribe(v -> setWallpaperOnSeparateThread()); 

您想在io线程中执行任务,然后在主线程中执行任务。 为此,您可以使用一个Observable链接您的呼叫。

 AppObservable.bindFragment(this, Observable.just(0)) .observeOn(Schedulers.io()) .flatMap(v -> Observable.defer(() -> WallpaperHelper.setBitmapAsWallpaper(photoViewAttacher.getVisibleRectangleBitmap(), getBaseActivity()))) .delay(500, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) .subscribe(v -> loadFinishAnimationAfterSetWallpaper()); 

请注意我使用defer来表示您作为Observable异步任务,但您可以使用doOnNext调用替换flatMap调用。

 AppObservable.bindFragment(this, Observable.just(0)) .observeOn(Schedulers.io()) .doOnNext(v -> WallpaperHelper.setBitmapAsWallpaper(photoViewAttacher.getVisibleRectangleBitmap(), getBaseActivity())) .delay(500, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) .subscribe(v -> loadFinishAnimationAfterSetWallpaper()); 

实际上observeOn用于subcscriber线程,而subscribeOn用于可观察线程。 所以你应该扭转它们

 .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io())