RxJava:Java上的异步和基于事件响应式编程库;
RxJava基于观察者模式,主要有四个部分:观察者,被观察者,订阅,事件。
基本写法:
1、Observable与Observer
//被观察者
Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
}) ;
//观察者
Observer<Integer> observer = new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "onSubscribe: ");
}
@Override
public void onNext(Integer integer) {
Log.d(TAG, "onNext: " + integer);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError: ");
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete: ");
}
};
//建立连接
observable.subscribe(observer);
连起来写就成立RxJava引以为傲的链式操作:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
}).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "onSubscribe: ");
}
@Override
public void onNext(Integer integer) {
Log.d(TAG, "onNext: " + integer);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError: ");
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete: ");
}
});
ObservableEmitter:发射器,用来发出事件,可以发出三种类型的事件,通过调用onNext、onComplete、onError方法分别发出next事件,compltet事件,error事件。
按照以下规则发射事件:
1、可以发送无限个onNext,可以接收无限个onNext
2、当被观察者发送了onComplete后,被观察者onComplete之后的事件会继续发送,而观察者收到onComplete事件之后将不再继续接收事件;
3、当被观察者发送了onError后,被观察者onError之后的事件会继续发送,而观察者收到onError事件之后将不再继续接收事件;
4、被观察者可以不发送onComplete或onError
5、onComplete和onError必须唯一并互斥,即不能发多个onComplete, 也不能发多个onError, 也不能先发一个onComplete, 然后再发一个onError, 反之亦然
Disposable:字面意思一次性用品,在RxJava中可以理解成一个开关,当调用它的dispose方法时,就会切断被观察者与观察者之间的联系,导致收不到事件。
RxJava的线程控制:
通常情况下,被观察者与观察者都工作在同一个线程中,然而我们在开发中经常需要将耗时操作放到子线程,然后回到主线程更新UI,要达到这个目的,需要先改变发送事件的线程,让它到子线程中取发送事件,然后在到主线程接收事件,通过RxJava内置的线程调度器可以轻松实现:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
Log.d(TAG, "subscribe: " + Thread.currentThread().getName());
}
})
.subscribeOn(Schedulers.newThread()) //发送
.observeOn(AndroidSchedulers.mainThread()) //接收
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.d(TAG, "accept: " + integer);
Log.d(TAG, "accept: " + Thread.currentThread().getName());
}
});
其中,subscribeOn()指的是被观察者发送的事件的线程,observeOn()指的是观察者接收事件的线程;多次指定被观察者的线程只有第一次指定有效,而观察者的线程每调用一次observeOn()就会切换一次。
在RxJava中, 已经内置了很多线程选项供我们选择, 例如有
Schedulers.io() 代表io操作的线程, 通常用于网络,读写文件等io密集型的操作
Schedulers.computation() 代表CPU计算密集型的操作, 例如需要大量计算的操作
Schedulers.newThread() 代表一个常规的新线程
AndroidSchedulers.mainThread() 代表Android的主线程
变换操作符
Map:对发送的每一个事件应用一个函数,使得每一个事件都按照指定的函数去变化:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
})
.map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return "this result is " + integer;
}
})
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d("main", "accept: " + s);
}
});
我们发送的Integer类型,经过中间map操作符的转换接收到的是String类型
FlatMap:
将一个发送事件的Observable变换为多个Observables,然后在合并成一个新的Observable:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
})
.flatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer integer) throws Exception {
List<String> list = new ArrayList<String>();
for (int i = 0; i < 3; i++){
list.add("result is " + integer);
}
Log.d("main", "apply: " + list.size());
return Observable.fromIterable(list);
}
})
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d("main", "accept: " + s);
}
});
Zip操作符:通过Zip操作符将多个Observable发送的事件结合到一起,然后发送这些组合事件,发射的数据量与最少的那个Observable一样多。
需要注意的是:
1、组合的过程是分别从每个Observable里个取出一个事件来组合,并且一个事件只能被使用一次,组合的顺序是严格按照发送的顺序来进行的;
2、最终Observer收到的事件数量是和发送事件中最少的那一个Observable的事件数量相同。
Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(11);
emitter.onNext(12);
emitter.onNext(13);
emitter.onComplete();
}
});
Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("A");
emitter.onNext("B");
emitter.onNext("C");
emitter.onComplete();
}
});
Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {
@Override
public String apply(Integer integer, String s) throws Exception {
return integer + s;
}
})
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d("main", "accept: " + s);
}
});
Flowable与Subscriber
和Obserable与Observer一样,Flowable(被观察者)与Subscriber(观察者)也是通过subscribe连接的,基本用法:
Flowable<Integer> flowable = Flowable.create(new FlowableOnSubscribe<Integer>() {
@Override
public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
}, BackpressureStrategy.ERROR);
Subscriber<Integer> subscriber = new Subscriber<Integer>() {
@Override
public void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE);
}
@Override
public void onNext(Integer integer) {
Log.d("main", "onNext: " + integer);
}
@Override
public void onError(Throwable t) {
}
@Override
public void onComplete() {
}
};
flowable.subscribe(subscriber);
从上面的代码可以看出和Observable不同的地方,首先创建Flowable的时候多增加了一个参数“BackpressureStrategy.ERROR”,这个参数是用来选择背压模式的,在出现上下游流速不均衡的时候的处理方法,有以下几种模式:
ERROR // 出现上下游速度不均衡时抛出异常MissingBackpressureException
DROP // 缓存指定大小的数据,多余的丢弃
BUFFER //新建一个缓冲区,缓冲所有发送的数据
LATEST // 保留最新的值
MISSING //不做任何缓存,全部由下游自己处理,一般在自定义背压处理的时候使用;
另外一个是在下游的onSubscribe方法中传入的不再是Disposable,而是Subscription,Subscription.cancel()与Disposable.dispose()效果一样,另外还增加了void request(Long n)方法,由于Flowable采用的是响应式拉取的方式来处理上下游流速不均衡的问题,request方法里的参数就表示下游能处理的数量;
另外推荐这两篇文章入门:
https://juejin.im/post/5848d96761ff4b0058c9d3dc
https://maxwell-nc.github.io/android/rxjava2-1.html