基本概念
默认情况下,上游和下游都在创建时所在的线程中工作,比如在Activity中创建的,那它们就在主线程中。Android中不能在主线程执行耗时操作,不然会造成应用的卡顿或发生ANR。比如上游需要从服务器请求数据,或者从数据库查询大量数据,完成后发布结果事件,下游根据接受的事件来显示界面,这时就需要控制上游和下游的线程了。
subscribeOn用于指定上游的线程;
public final Observable<T> subscribeOn(Scheduler scheduler)
observeOn用于指定下游的线程;
public final Observable<T> observeOn(Scheduler scheduler)
两个方法都接受调度器 Scheduler 参数,Scheduler 提供了不同的线程:
Schedulers. io() 代表io操作的线程
Schedulers.computation() 代表CPU计算密集型的操作
Schedulers.newThread() 代表一个常规的新线程
AndroidSchedulers.mainThread() 代表Android的主线程
如果只指定上游线程,不指定下游线程,下游线程和上游线程一样。
//Activity的onCreate方法
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Observable.create(new ObservableOnSubscribe<Object>() {
@Override
public void subscribe(ObservableEmitter<Object> e) throws Exception {
System.out.println("emit 1 thread " + Thread.currentThread().getName());
e.onNext(1);
e.onComplete();
}
}).subscribeOn(Schedulers.io())
.subscribe(new Observer<Object>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("A onSubscribe thread " + Thread.currentThread().getName());
}
@Override
public void onNext(Object o) {
System.out.println("A onNext o " + o + " thread " + Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
System.out.println("A onError" + e + " thread " + Thread.currentThread().getName());
}
@Override
public void onComplete() {
System.out.println("A onComplete thread " + Thread.currentThread().getName());
}
});
}
//打印结果
System.out: A onSubscribe thread main
System.out: emit 1 thread RxCachedThreadScheduler-1
System.out: A onNext o 1 thread RxCachedThreadScheduler-1//与上游线程相同
System.out: A onComplete thread RxCachedThreadScheduler-1
如果只指定下游线程,不指定上游线程,上游线程为当前线程。
//Activity的onCreate方法
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Observable.create(new ObservableOnSubscribe<Object>() {
@Override
public void subscribe(ObservableEmitter<Object> e) throws Exception {
System.out.println("emit 1 thread " + Thread.currentThread().getName());
e.onNext(1);
e.onComplete();
}
}).observeOn(Schedulers.io())
.subscribe(new Observer<Object>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("A onSubscribe thread " + Thread.currentThread().getName());
}
@Override
public void onNext(Object o) {
System.out.println("A onNext o " + o + " thread " + Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
System.out.println("A onError" + e + " thread " + Thread.currentThread().getName());
}
@Override
public void onComplete() {
System.out.println("A onComplete thread " + Thread.currentThread().getName());
}
});
}
//打印结果
System.out: A onSubscribe thread main
System.out: emit 1 thread main //上游线程为当前主线程
System.out: A onNext o 1 thread RxCachedThreadScheduler-1
System.out: A onComplete thread RxCachedThreadScheduler-1
从上面测试结果可以发现,无论上游和下游指定什么线程,onSubscribe方法的线程始终是执行订阅操作所在的主线程,也就是我们虽然可以指定上游下游的线程,但是却无法指定onSubscribe方法的线程。假如订阅操作不是在主线程,我需要在 onSubscribe 时通知界面,就会很难受。所幸,RxJava 提供了doOnSubsricbe 方法,该方法也是在订阅时调用(如果上游下游同一线程onSubscribe 比onSubscribe 调用早,否则不是),并且我们可以指定它的执行线程,通过subscribeOn来指定。
//Activity的onCreate方法
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Observable.create(new ObservableOnSubscribe<Object>() {
@Override
public void subscribe(ObservableEmitter<Object> e) throws Exception {
System.out.println("emit 1 thread " + Thread.currentThread().getName());
e.onNext(1);
e.onComplete();
}
}).doOnSubscribe(new Consumer<Disposable>() {
@Override
public void accept(Disposable disposable) throws Exception {
System.out.println("doOnSubscribe thread " + Thread.currentThread().getName());
}
}).subscribeOn(Schedulers.newThread())
.observeOn(Schedulers.newThread())
.subscribe(new Observer<Object>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("A onSubscribe thread " + Thread.currentThread().getName());
}
@Override
public void onNext(Object o) {
System.out.println("A onNext o " + o + " thread " + Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
System.out.println("A onError" + e + " thread " + Thread.currentThread().getName());
}
@Override
public void onComplete() {
System.out.println("A onComplete thread " + Thread.currentThread().getName());
}
});
}
//打印结果
System.out: A onSubscribe thread main
System.out: doOnSubscribe thread RxNewThreadScheduler-1//doOnSubscribe 在指定的线程中
System.out: emit 1 thread RxNewThreadScheduler-1
System.out: A onNext o 1 thread RxNewThreadScheduler-2
System.out: A onComplete thread RxNewThreadScheduler-2
subscribeOn作用范围是从它开始往上,如果多次调用subscribeOn,上游的线程为从下往上,离它最近的那个subscribeOn指定的线程
Observable.create(new ObservableOnSubscribe<Object>() {
@Override
public void subscribe(ObservableEmitter<Object> e) throws Exception {
System.out.println("emit 1 thread " + Thread.currentThread().getName());
e.onNext(1);
e.onComplete();
}
}).subscribeOn(Schedulers.newThread())// subscribeOn 1
.doOnSubscribe(new Consumer<Disposable>() {
@Override
public void accept(Disposable disposable) throws Exception {
System.out.println("doOnSubscribe thread " + Thread.currentThread().getName());
}
})
.doOnNext(new Consumer<Object>() {
@Override
public void accept(Object o) throws Exception {
System.out.println("doOnNext o " + o + " thread " + Thread.currentThread().getName());
}
})
.subscribeOn(Schedulers.newThread())// subscribeOn 2
.subscribeOn(AndroidSchedulers.mainThread())// subscribeOn 3
.observeOn(Schedulers.newThread())
.subscribe(new Observer<Object>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("A onSubscribe thread " + Thread.currentThread().getName());
}
@Override
public void onNext(Object o) {
System.out.println("A onNext o " + o + " thread " + Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
System.out.println("A onError" + e + " thread " + Thread.currentThread().getName());
}
@Override
public void onComplete() {
System.out.println("A onComplete thread " + Thread.currentThread().getName());
}
});
//打印结果
System.out: A onSubscribe thread main
System.out: doOnSubscribe thread RxNewThreadScheduler-1
System.out: emit 1 thread RxNewThreadScheduler-2
System.out: doOnNext o 1 thread RxNewThreadScheduler-2
System.out: A onNext o 1 thread RxNewThreadScheduler-3
System.out: A onComplete thread RxNewThreadScheduler-3
subscribeOn 1 控制发布事件的线程,subscribeOn 2 控制 doOnSubscribe 的线程,subscribeOn 3 是多余的。
另外除了 doOnSubscribe 以外,还有对应的 doOnNext,doOnComplete,doOnError,这三个方法的线程始终与发布事件的线程相同。
observeOn作用范围是从它开始往下,如果多次调用 observeOn,下游的线程为从上往下,离它最近的那个 observeOn 指定的线程
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
System.out.println("emit 1 thread " + Thread.currentThread().getName());
e.onNext("friend");
e.onComplete();
}
}).subscribeOn(Schedulers.newThread())
.observeOn(Schedulers.newThread())// observeOn 1
.map(new Function<String, Integer>() {
@Override
public Integer apply(String o) throws Exception {
System.out.println("map thread " + Thread.currentThread().getName());
return 10;
}
})
.observeOn(Schedulers.newThread())// observeOn 2
.observeOn(AndroidSchedulers.mainThread())// observeOn 3
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("A onSubscribe thread " + Thread.currentThread().getName());
}
@Override
public void onNext(Integer o) {
System.out.println("A onNext o " + o + " thread " + Thread.currentThread().getName()
}
@Override
public void onError(Throwable e) {
System.out.println("A onError" + e + " thread " + Thread.currentThread().getName());
}
@Override
public void onComplete() {
System.out.println("A onComplete thread " + Thread.currentThread().getName());
}
});
//打印结果
System.out: A onSubscribe thread main
System.out: emit 1 thread RxNewThreadScheduler-1
System.out: map thread RxNewThreadScheduler-2
System.out: A onNext o 10 thread main
System.out: A onComplete thread main
observeOn 1 控制 map 操作的线程,map 操作符是一个中间商,拦截上游的数据,进行加工后再返回给下游。
observeOn 2 是多余的。
observeOn 3 控制接受事件的线程。