闲谈RxJava
- RxJava:"a library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库)
- 异步。它其实就是一个实现异步操作的库,基于观察者模式,而且是链式调用的。
RxJava的三个基本元素
被观察者(Observable)、观察者(Observer)、订阅(subscribe)。
1、创建被观察者:
Observable observable = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
e.onNext(0);
e.onNext(1);
e.onNext(2);
e.onComplete();
}
});
2、创建观察者:
Observer observer = new Observer() {
@Override
public void onSubscribe(Disposable d) {}
@Override
public void onNext(Integer o) {}
@Override
public void onError(Throwable e) {}
@Override
public void onComplete() {}
};
3、建立订阅关系:
observable.subscribe(observer);
- 被观察者的创建常用三种:
Observable.create((ObservableOnSubscribe<Integer>) emitter -> {
emitter.onNext(0);
emitter.onNext(1);
emitter.onNext(2);
emitter.onComplete();
});
Observable.just(0);
Observable.fromIterable(Arrays.asList(0,1, 2));
- 观察者的创建有两种:
Observer observer = new Observer() {
@Override
public void onSubscribe(Disposable d) {}
@Override
public void onNext(Integer o) {}
@Override
public void onError(Throwable e) {}
@Override
public void onComplete() {}
};
Consumer<Integer> consumer = new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {}
};
- 订阅关系有四种:
Disposable subscribe();
void subscribe(Observer<? super T> observer);
Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError,Action onComplete, Consumer<? super Disposable> onSubscribe);
<E extends Observer<? super T>> E subscribeWith(E observer);
调度器Scheduler
- Schedulers.computation():代表CPU计算密集型的操作, 例如需要大量计算的操作。
- Schedulers.newThread():直接开启一个新的线程。
- Schedulers.io():开启一个io线程,完成对网络请求和文件读写数据库增删改查等操作。那io和newThread有什么区别呐?newThread不管有没有线程,他都会去重新开启一个新的线程来进行操作,并且没线程池维护。但是io的线程是无上限的,并且最大的一个好处是它会去重用空闲的线程,而不是每次都开启一个线程来使用,效率上比newThread要高。所以,一般我们在使用的时候是直接使用io这个方法。
- AndroidSchedulers.mainThread():android一个专门的线程,用来指定操作在主线程完成。
RxJava实现线程切换
subscribeOn():指定Observable被观察者在哪个线程执行。要注意的是,如果多次调用此方法,只有第一次有效。
observeOn():指定Observe观察者在哪个线程中执行。多次指定观察者接收线程是可以的,每调用一次observerOn(),下游的线程就会切换一次。
- 代码探索:
Observable.just(0)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(integer -> {
Log.i(TAG, "integer=" + integer + ",当前线程mainThread = " + Thread.currentThread().getName());
return ++integer;
})
.observeOn(Schedulers.io())
.map(integer -> {
Log.i(TAG, "integer=" + integer + ",当前线程io = " + Thread.currentThread().getName());
return ++integer;
})
.observeOn(Schedulers.newThread())
.map(integer -> {
Log.i(TAG, "integer=" + integer + ",当前线程newThread = " + Thread.currentThread().getName());
return ++integer;
})
.observeOn(Schedulers.computation())
.map(integer -> {
Log.i(TAG, "integer=" + integer + ",当前线程computation = " + Thread.currentThread().getName());
return ++integer;
})
.observeOn(Schedulers.single())
.map(integer -> {
Log.i(TAG, "integer=" + integer + ",当前线程single = " + Thread.currentThread().getName());
return ++integer;
})
.observeOn(AndroidSchedulers.mainThread())
.map(integer -> {
Log.i(TAG, "integer=" + integer + ",当前线程mainThread = " + Thread.currentThread().getName());
return ++integer;
})
.subscribe();
- log日志:
MyAppUtils: integer=0,当前线程mainThread = main
MyAppUtils: integer=1,当前线程io = RxCachedThreadScheduler-3
MyAppUtils: integer=2,当前线程newThread = RxNewThreadScheduler-1
MyAppUtils: integer=3,当前线程computation = RxComputationThreadPool-1
MyAppUtils: integer=4,当前线程single = RxSingleScheduler-1
MyAppUtils: integer=5,当前线程mainThread = main
Subject
- AsyncSubject:无论输入多少参数、什么时候订阅、是否Completed,永远只输出最后一个参数;
- BehaviorSubject:发送离订阅最近的上一个值,没有上一个值的时候会发送默认值;
- PublishSubject:最正常的Subject,从那里订阅就从那里开始发送数据;
- ReplaySubject:无论何时订阅,都会将所有历史订阅内容全部发出。