在正确的线程上使用Observable【译】
尽管很多人了解 RxJava 的基本逻辑,但是在 Observable 链和操作符究竟运行在哪个线程,仍然会有许多困惑。
首先,让我们梳理清晰,在 RxJava 中 .subsribeOn()
和 .observeOn()
区别:
.subsribeOn()
操作符可以改变 Observable 应该在哪个调度器上执行任务。.observeOn()
操作符可以改变 Observable 将在哪个调度器上发送通知。- 另外,你需要知道,默认情况下,链上的操作符将会在调用
.subsribeOn()
的那个线程上执行任务。
一些例子
主线程或者 .subscribe() 所在线程
如果在 Android 的 Activity下onCreate()
方法中,也就是主线程中使用如下代码:
1 | Observable.just(1,2,3) |
表现会像这样:
调用 .subscribeOn()
尽管代码片段在主线程中,但是整个代码块将运行在 .subscribeOn()
定义的线程上:
1 | Observable.just(1,2,3) |
表现会像这样:
调用 .observeOn()
如果你的代码片段在主线程中,默认情况下Observable的创建是在 .subscribeOn()
定义的线程上,但是,调用 .observeOn()
之后,余下的代码将会执行在 .observeOn()
所定义的线程上:
1 | Observable.just(1,2,3) |
合并逻辑
照理合并操作符,放在一起就像这样:
1 | Observable.just(1,2,3) |
一些技巧
UI 线程运行异常
1 | Observable.just(1,2,3) |
很明显,这是错的。
保证逻辑运行在工作线程中
如果存在以下代码片段:
1 | Observable.just(1,2,3) |
请用以下代码替代:
1 | Observable.just(1,2,3) |
通过用第二段代码代替第一段,.flatMap()
操作符(或者在这一点的其他逻辑操作符)将运行在后台线程。这样做就不会阻塞 UI 线程,同时可以防患 ANR 或其他类似问题的发生。看起来有点像 AsyncTask
模式,尽可能的把逻辑放在的 .doInBackground()
中,而不是 .onPostExecute()
。
取决于更早的 .subscribeOn()
以下代码:
1 | Observable.just(1,2,3) |
因为 thread1
的逻辑将会覆盖 thread2
,所以 Observable
的创建和 .subscribe()
的逻辑处理都将运行在 thread1
中。因此,根本没有必要写多个 .subscribeOn()
操作符。
原文链接:
Observe on the correct thread