RxAndroid: UI changes in Schedulers.io () thread

I have a simple work on an I / O thread that changes the desktop wallpaper, after which I try to run an animation on the UI thread:

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

      

but this approach results in an error: java.lang.IllegalStateException: Observers must subscribe from the main UI thread, but was Thread[RxCachedThreadScheduler-1,5,main]

I tried to change the second Observable to:

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

      

But it did not help.

+3


source to share


2 answers


AppObservable.bindFragment(this, Observable.just(0))

throws an exception as it is not called from the main thread

This code is not called on the main thread, because you observe Schedulers.io

in this code (see below) than the last callAppObservable.bindFragment(this, Observable.just(0))

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

      

You want to execute a task on the io thread and then execute the task on the main thread. To do this, you can link the call using one 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());

      

Please note, I am using defer

to represent your asynchronous task as Observable

, but you can replace call flatMap

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

      

+10


source


In fact, observOn is for the subhead stream, and subscribeOn is for the observable thread. Therefore you must undo them



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

      

+5


source







All Articles