RxAndroid:UI 在 Schedulers.io() 线程上发生变化
RxAndroid: UI changes on Schedulers.io() thread
我在 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());
但是没有用。
其实observeOn是针对subscriber线程的,而subscribeOn是针对observable线程的。所以你应该反转它们
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
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
,但您可以将 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());
我在 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());
但是没有用。
其实observeOn是针对subscriber线程的,而subscribeOn是针对observable线程的。所以你应该反转它们
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
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
,但您可以将 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());