簡體   English   中英

RxAndroid:在Schedulers.io()線程上更改UI

[英]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());

但它沒有幫助。

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調用替換flatMap調用。

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

實際上observeOn用於subcscriber線程,而subscribeOn用於可觀察線程。 所以你應該扭轉它們

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM