- 原文鏈接:Observe on the correct thread
- 原文作者: Dionysis Lorentzos
- 譯文出自: 小鄧子的簡書
- 譯者: 小鄧子
- 狀態(tài): 完成
盡管很多人了解RxJava的基本邏輯垛耳,但是在Observable鏈和操作符究竟運行在哪個線程桌硫,仍然會有許多困惑杈帐。
首先法梯,讓我們梳理清晰嫁盲,在RxJava中.subsribeOn( )
和.observeOn( )
區(qū)別:
.subsribeOn( )
操作符可以改變Observable應(yīng)該在哪個調(diào)度器上執(zhí)行任務(wù)勺远。.observeOn( )
操作符可以改變Observable將在哪個調(diào)度器上發(fā)送通知塘偎。另外,你需要知道涨享,默認(rèn)情況下,鏈上的操作符將會在調(diào)用
.subsribeOn( )
的那個線程上執(zhí)行任務(wù)仆百。
一些例子##
1. 主線程或者 .subscribe( )所在線程
如果在Android的Activity下onCreate( )
方法中厕隧,也就是主線程中使用如下代碼:
Observable.just(1,2,3)
.subscribe( );
表現(xiàn)會像這樣:
2. 調(diào)用 .subscribeOn( )
盡管代碼片段在主線程中,但是整個代碼塊將運行在.subscribeOn( )
定義的線程上:
Observable.just(1,2,3)
.subscribeOn(Schedulers.newThread())
.subscribe();
表現(xiàn)會像這樣:
3. 調(diào)用 .observeOn( )
如果你的代碼片段在主線程中俄周,默認(rèn)情況下Observable的創(chuàng)建是在.subscribeOn( )
定義的線程上吁讨,但是,調(diào)用.observeOn( )
之后峦朗,余下的代碼將會執(zhí)行在.observeOn( )
所定義的線程上:
Observable.just(1,2,3)
.observeOn(Schedulers.newThread())
.subscribe();
3. 合并邏輯
照理合并操作符建丧,放在一起就像這樣:
Observable.just(1,2,3)
.subscribeOn(Schedulers.newThread())
.observeOn(Schedulers.newThread())
.subscribe();
一些技巧##
1. UI線程運行異常
Observable.just(1,2,3)
.subscribeOn(Schedulers.newThread())
.subscribe(/** 與UI線程相關(guān)的邏輯 **//);
很明顯,這是錯誤噠波势。
2. 保證邏輯運行在工作線程中
如果存在以下代碼片段:
Observable.just(1,2,3)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(/** 與UI線程無關(guān)的邏輯**//)
.subscribe();
請用以下代碼替代:
Observable.just(1,2,3)
.subscribeOn(Schedulers.newThread())
.flatMap(/** 與UI線程無關(guān)的邏輯**//)
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
通過用第二段代碼代替第一段搂橙,.flatMap( )
操作符(或者在這一點的其他邏輯操作符)將運行在后臺線程。這樣做就不會阻塞UI線程坛增,同時可以防患ANR或其他類似問題的發(fā)生游沿。看起來有點像AsyncTask模式蔫慧,盡可能的把邏輯放在的.doInBackground( )
中,而不是.onPostExecute( )
。
3. 取決于更早的 .subscribeOn( )
以下代碼:
Observable.just(1,2,3)
.subscribeOn(thread1)
.subscribeOn(thread2)
.subscribe();
因為thread1的邏輯將會覆蓋thread2兑障,所以O(shè)bservable的創(chuàng)建和.subscribe( )
的邏輯處理都將運行在thread1中。因此蕉汪,根本沒有必要寫多個.subscribeOn( )
操作符流译。