RxJava之功能操作符subscribeOn()和observeOn()
1、功能操作符subscribeOn()和observeOn()都与线程切换有关。subscribeOn():它与调用位置无关,放在那里都可以,并且写一个subscribeOn()操作符和写多个的结果是一样的,因为代码只会调用第一个subscribeOn()操作符,第二个第三个等其它的subscribeOn()操作符,代码都不会调用,所以我们一般只需写一个subscribeOn()操作符即可。observeOn():它与调用位置有关,写一个observeOn()和写多个的结果是不一样的,每写一个observeOn()操作符,它下面代码的执行线程就会切换一次。
2、RxJava中的线程调度是在Scheduler的帮助下完成的。接下来的代码例子中有两种类型的线程调度。1、Schedulers.newThread():它会调用RxNewThreadScheduler这种类型的线程。它调用的线程都是新建的。2、Schedulers.io():它会调用RxCachedThreadScheduler这种类型的线程。它调用的线程不是新建的,是线程池中的。
3、使用线程池的好处1、降低资源的消耗:通过重复利用已有的线程,避免多次创建和销毁线程。2、提高系统的性能:省略了创建线程的步骤。
4、接下来讲一下代码例子。代码分为两部分,第一部分为创建观察者,第二部分为操作符的使用。这个代码是还没有使用操作符之前的样子。
5、运行结果如图所示。我们可以看到线程用的都是主线程。代码运行的顺序:onSubscribe--》subscribe--》onNext--》onComplete。
6、因为创建观察者的代码基本没有改变,所以就不截图了。现在我们为代码添加上subscribeOn()操作符。
7、运行结果如图所示。我们可以看到除了onSubscribe方法用的依然是主线程外,其它的都调用了另外一个线程。在接下来的代码例子中,我们会发现onSubscribe方法调用的都是主线程,因为根据第五个步骤中的代码运行顺序,可以知道onSubscribe方法是第一个运行的,这时还没有切换线程,所以用的还是主线程。
8、现在我们为代码添加上observeOn()操作符。
9、运行结果如图所示。很明显这种运行结果是不完整的。
10、我们为代码加上红色方框中的内容,就可以得到完整的运行结果。
11、运行结果如图所示。这次的运行结果就完整了。因为subscribe方法在observeOn()操作符的上面,所以用的还是subscribeOn()操作符调用的线程。
12、我们在添加一个observeOn()操作符,来验证observeOn()操作符可以多次切换线程的能力。
13、运行结果如图所示。我们可以发现线程由RxCachedThreadScheduler-1变成了RxCachedThreadScheduler-2。
14、我们老揉孟阼写两个map操作符和两个observeOn()操作符,第一个map操作符上面没有observeOn()操作符,第二个map操作符上面有observeOn()操作符。这个例子是验证observeOn()操作符下面的代码会切换线程的能力。observeOn()操作符上面的代码不会切换线程,它下面的代码才会切换线程。
15、运行结果如图所示。我们可以发现第一个map和第二个map,还有onNext方法使用的线程都不一样。第一个map因为上面没有observeOn()操作符,所以用的是subscribeOn(像粜杵泳)操作符调用的线程。第二个map因为上面有observeOn()操作符,所以用的是observeOn()操作符切换后的线程。onNext方法的线程不一样的原因是,第二个observeOn()操作符导致的。
16、可能你会好奇,为什么会有两个" 第一个map "和" 第二个map ",其实这个问题和为什么会有两个onNext方法是一样的。因为我们发送两个事件,如果我们发送一个事件,那么" 第一个map "和" 第二个map "都会变成一个。
17、运行结果如图所示。
18、可能你会好奇经过两个map操作符后,事件最终到底是" 你好 " 还是 " 你好啊啊啊啊啊啊 "。我们可以添加红色方框中的内容来查看。
19、运行结果如图所示。这可以说明,当有多个map操作符时,以最后一个map操作符返回的结果作为最终的结果。