I have simple job on IO thread which is changing home screen wallpaper, after that I'm trying to run some animation on 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 error:
java.lang.IllegalStateException: Observers must subscribe from the main UI thread, but was Thread[RxCachedThreadScheduler-1,5,main]
I've tried to change second Observable to:
AppObservable.bindFragment(this, Observable.just(0))
.delay(2000, TimeUnit.MILLISECONDS)
.observeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(integer -> loadFinishAnimationAfterSetWallpaper());
But it didn't help.
AppObservable.bindFragment(this, Observable.just(0))
throw an exception as it's not called from the Main Thread
This code is not called in the main thread because you observe on Schedulers.io
in this code (see bellow), than latter call AppObservable.bindFragment(this, Observable.just(0))
AppObservable.bindFragment(this, Observable.just(0))
.observeOn(Schedulers.io())
.subscribe(v -> setWallpaperOnSeparateThread());
You want to perform a task in io thread, then perform a task in main thread. To do so, you can chain you 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 use defer
to represente you async task as an Observable
but you can replace the flatMap
call with doOnNext
call.
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());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With