2015-05-13 2 views
3

У меня есть простое задание на IO нити, которая меняет обои на домашнем экране, после того, что я пытаюсь запустить анимацию на UI нити: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()); 

Но это не помогло.

ответ

10

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 для represente вас асинхронной задачи как Observable но вы можете заменить flatMap вызов с 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()); 
+0

doOnNext() с задержкой() решил мою проблему - поддержал это –

5

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

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

Такая же проблема здесь. – czajna666

+0

такой же исключение в этом случае. – czajna666