在Andoid中如何使用RxJava 2进行多线程编程?(5)

我们从片段的最后一行开始理解这段代码。在这里,目标订阅者(或者说链中最下游的observer)基于observable o3调用subscribe()方法,这样会隐式地对它的直接上游observable o2调用subscribe()方法。o3所提供的observer实现会将生成的数字乘以10。

这个过程会重复进行,o2会隐式地基于o1调用subscribe,所传入的observer实现会将偶数过滤出来并允许其通过。现在,我们到达了根部,源observable o1没有任何上游observable来调用subscribe。这实际上就完成了observable链,源observable就能生成其条目了

对于RxJava中订阅是如何实现的,读者应该就会比较清楚了。到目前为止,对observable链如何组成以及事件如何从源observable开始在链中传播应该有了一个基本的了解。

observeOn()

正如我们刚刚看到的,subscribeOn()能够指明源observable要在一个特定的线程中生成其条目,这个线程还会负责将这些条目一直推送到sink Subscriber中。因此,默认情况下,订阅者也会在这个线程中消费这些条目

但是,我们的应用所期望的行为往往并非总是如此。假设,我们想要通过网络获取一些数据并在App的UI中展现。

本质上,我们有两件事情需要完成:

在非阻塞的I/O线程上执行网络调用;

在应用的主(UI)线程上消费得到的结果。

我们需要有一个observable在I/O线程进行网络调用,并将产出传递给目标订阅者。如果你只是使用subscribeOn()和Schedulers.io()的话,最终的订阅者将会在I/O线程中进行操作。我们无法在主线程之外的其他线程中访问UI组件,因此我们如果这样做的话,会遇到麻烦。

现在,我们迫切需要切换线程,而这就是observeOn()操作符能够发挥作用的地方。在observable链中,如果遇到observeOn(),那么产出物将会立即切换到所指定的线程中。

getIntegersFromRemoteSource() .doOnNext(integer -> println("Emitting item " + integer + " on: " + currentThread().getName())) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(integer -> println("Consuming item " + integer + " on: " + currentThread().getName()));

在这个稍微有点牵强的样例中,我们有一个observable从网络上获取整数所组成的流。在实际的用例中,这可以换成任意的异步操作,比如读取大文件或从数据库获取数据等等。你可以尝试该代码片段并查看结果,需要关注的是日志中的线程名。

现在,我们看一个稍微复杂一点的样例,这里会使用多个observeOn()操作符,这样在我们的observable链中会多次切换线程。

getIntegersFromRemoteSource() .doOnNext(integer -> println("Emitting item " + integer + " on: " + currentThread().getName())) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.computation()) .map(integer -> { println("Mapping item " + integer + " on: " + currentThread().getName()); return integer * integer; }) .observeOn(Schedulers.newThread()) .filter(integer -> { println("Filtering item " + integer + " on: " + currentThread().getName()); return integer % 2 == 0; }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(integer -> println("Consuming item " + integer + " on: " + currentThread().getName()));

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/d1e341f4e14e0d4b847772148355d24a.html