RxAndroid: изменения пользовательского интерфейса в потоке Schedulers.io ()

У меня есть простая работа над потоком ввода-вывода, который меняет обои рабочего стола, после чего я пытаюсь запустить анимацию в потоке пользовательского интерфейса:

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]

Я попытался изменить второе Наблюдаемое:

  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)) исключение, поскольку оно не AppObservable.bindFragment(this, Observable.just(0)) из главной темы

Этот код не вызывается в основном потоке, потому что вы наблюдаете в 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 вызовом doOnNext .

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

Фактически observOn предназначен для потока подсетей, а subscribeOn – для наблюдаемой нити. Поэтому вы должны обратить вспять их

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