RxJava实现线程调度
RxJava 遵循的是线程不变的原则,即:在哪个线程调用 subscribe(),就在哪个线程生产事件;在哪个线程生产事件,就在哪个线程消费事件。如果需要切换线程,就需要用到 Scheduler (调度器)。
常用的Rxjava内置线程:
Schedulers.io()
:代表io操作的线程, 通常用于网络,读写文件等io密集型的操作;
Schedulers.newThread()
:代表一个常规的新线程;
AndroidSchedulers.mainThread()
:代表Android的主线程;
RxJava可以对线程进行自由控制,有了这些线程之后,便可以使用 subscribeOn()
和 observeOn()
两个方法来对线程进行控制。
- subScribeOn()
用于指定 subscribe() 时所发生的线程,也就是发射事件的线程,多次指定只有第一次指定的有效。 - observeOn()
用于指定 Observer 回调发生的线程,也就是接收事件的线程,可以多次指定,每调用一次observerOn(),接收的线程就会切换一次。
代码实现:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
Log.e(TAG, "Observable的线程: " + Thread.currentThread().getName());
e.onNext(1);
e.onComplete();
}
}).subscribeOn(Schedulers.newThread())//新线程
.doOnNext(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
Log.e(TAG, "1现在的线程是: " + Thread.currentThread().getName());
}
})
.subscribeOn(Schedulers.io())//发射事件的线程 io操作的线程 不起作用
.doOnNext(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
Log.e(TAG, "2现在的线程是: " + Thread.currentThread().getName());
}
})
.observeOn(AndroidSchedulers.mainThread())//接收事件的线程 主线程
.doOnNext(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
Log.e(TAG, "observeOn(mainThread)线程之后,现在的线程是: " + Thread.currentThread().getName());
}
})
.observeOn(Schedulers.io())
.doOnNext(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
Log.e(TAG, "3现在的线程是: " + Thread.currentThread().getName());
}
})
.subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
Log.e(TAG, "observeOn(io)线程之后,现在的线程是: " + Thread.currentThread().getName());
}
});
记得添加RxAndroid的依赖:
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
可以看到第二次调用subscribeOn()已经不起作用了,都是在“RxNewThreadScheduler-1”这个线程中使用,但每调用一次 observeOn() ,线程便会切换一次。