2017-10-06 197 views
1

我正在處理這個問題。BlockingGet塊UI線程RxJava 2

我試圖打電話RxJava在同步方式,但是這樣做的結果阻斷主線程。

這裏是我的代碼

@Override 
    public Single<SettingsBundle> getSettings() { 
     SettingsBundle settingsModel = mSettingsManager.getSettings(); 
     return Single.just(settingsModel).map(mSettingsMapper); 
    } 

這裏是我的電話同步

@Override 
    public SettingsBundle getSettingsSync() { 
     return getSettings().blockingGet(); 
    } 

當調用getSettingsSync主線程被阻塞,但有時它工作得很好,更重要的是有問題的。

我已經試過類似的東西

@Override 
public SettingsBundle getSettingsSync() { 
    return getSettings() 
      .subscribeOn(Schedulers.newThread()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .blockingGet(); 
} 

但它劇照仍然受阻。

什麼我做錯了,我會很感謝任何幫助。

謝謝。

+0

阻塞所有將阻塞,直到有數據。不要在UI線程上使用一個。要麼有另一個線程執行它,要麼使用非阻塞調用。 –

+0

究竟是什麼問題? 'blockingGet()'調用會阻塞_current_線程直到數據可用,這是預期的行爲。你想實現什麼? –

+0

@GergelyKőrössy,它不會得到釋放導致我的線程卡住 – bxfvgekd

回答

1
.observeOn(AndroidSchedulers.mainThread()) 
.blockingGet(); 

這個問題存在於這個特定的運算符組合中。 AndroidSchedulers計劃在主線程上運行代碼,但blockingGet()停止在該線程上執行更多代碼。簡單地說,AndroidSchedulersRxJava的阻塞運算符不能很好地協同工作。

由於android調度程序可能用於構建observable,這意味着主線程上任何對blocking*運算符的使用都將很容易出現死鎖,無論您嘗試做什麼。

0

TL,TR

從來沒有使用observeOn(AndroidSchedulers.mainThread())blockingGet()


龍版

的輸出:

class MainActivity : AppCompatActivity() { 

    override fun onCreate(savedInstanceState: Bundle?) { 
     super.onCreate(savedInstanceState) 
     setContentView(R.layout.activity_main) 

     val result = 
       Single.just("Hello") 
       .subscribeOn(Schedulers.io()) 
       // .observeOn(AndroidSchedulers.mainThread()) 
       .map { 
        println("1. blockingGet `$it` thread: ${Thread.currentThread()}") 
        [email protected] it 
       } 
       .blockingGet() 
     println("2. blockingGet `$result` thread: ${Thread.currentThread()}") 
    } 
} 

1. blockingGet `Hello` thread: Thread[RxCachedThreadScheduler-1,5,main] 
2. blockingGet `Hello` thread: Thread[main,5,main] 

正如你可以看到在主線程(線2)產生結果,地圖功能是在RxCachedThreadScheduler線程中執行。

隨着線.observeOn(AndroidSchedulers.mainThread()) decommented的blockingGet()不會再回來,一切都stucked。