最近在使用RxJava,简单记录下RxJava的相关使用方法
1、相关概念
被观察者:Observable
观察者:Observer
发射器:ObservableEmitter
简化版观察者:Consumer
背压模式下被观察者:Flowable
背压模式下观察者:Subscriber
2、操作符
2.1 创建型操作符:创建被观察者
create:使用者自己发射事件
just:内部自己发射事件,单一对象
fromArray:内部自己发射事件,集合对象
empty:内部自己发射事件,下游默认是Object,无法发射有值事件,只会发射onComplete
range:内部自己发射事件,一个范围内的事件
2.2 变换型操作符:上一层的事件类型 ------》格式转换 ------》 下一层需要的事件类型
map:直接转换,int ----》 String
flatMap:多次发射事件,无序
concatMap:多次发射事件,有序
groupBy:排序
buffer:100个事件,buffer(20),观察者List会有5个集合
2.3 过滤型操作符:上一层事件 -----》 过滤筛选 -----》 下一层
filter:false:全部发射给下一层;true:全部不发射给下一层
take:定时器运行基础上加入take过滤器操作符,才有take过滤操作符的价值
distinct:去重
elementAl:指定发射事件内容,无法指定,有默认的事件
2.4 条件型操作符:上一层的事件 ----》 是否满足条件 —》 下一层
All:如同if的功能,全部为true,才是true;只要有一个false,就是false
contains:包含
any:全部是false,才是false;只要有一个为true,就是true
2.5合并型操作符:多个被观察者事件 ----》 合并成一个观察者 ----》 下一层
startWait、concatWith:先创建被观察者,然后组合其他的被观察者,最后在订阅
concat、merge、zip:直接合并多个被观察者,然后订阅
startWith:先执行括号里面的被观察者
concatWith:后执行括号里面的被观察者
concat:按照顺序依次执行,最多合并4个被观察者
merge:并列执行,最多合并4个被观察者
zip:需要对应关系,如果不对应,会被忽略,最多9个被观察者合并
2.6 异常操作符:上一层的事件 ----》 异常处理 -----》 下一层
标准版:e.onError(xxx);
onErrorReturn:最新拦截到e.onError并且可以给下游返回一个表示400,throw new xxx拦截不到,程序崩溃
onErrorResumeNext:最先拦截到e.onError并且可以给下游返回一个被观察者(还可以再次发送),throw new xxx拦截不到,程序崩溃
onExceptionResumeNext:能在发生异常的时候扭转乾坤,能够处理throw new xxx,可以真正的让app不崩溃
retry: return false:代表不去重试,true:不停的重试
2.7线程切换:默认情况下实在main线程中,异步线程io,主线程AndroidSchedulers.mainThread;给上游分配多次,只会在第一次切换,后面的就不切换了;给下游分配多次,每次都会去切换
Schedulers.io():代表io流操作,适用于网络操作,文件流,耗时操作
Schedulers.newThread():常规的开启子线程
Schedulers.computation():代表CPU需要大量的计算
AndroidSchedulers.mainThread():专门为Android main线程量身定做的
2.8 背压模式:上游大量的发射事件,下游处理不过来导致阻塞,就需要使用背压模式(ERROR、BUFFER)
RxJava 1.x时,没有背压模式,上游发射太多处理不过来,导致内存泄露
RxJava 2.x 增加背压模式,使用Flowable代替Observable,Subscriber代替Observer
背压策略:
BackpressureStrategy.Error:上游不停的发射事件,下游阻塞了处理不过来,放入缓存池,如果池子满了,就会抛出异常
BackpressureStrategy.BUFFER:上游不停的发射事件,下游阻塞了处理不过来,放入缓存池,等待下游来处理
BackpressureStrategy.MISSING:如果下游阻塞处理不过来了,但是事件还是必须处理的,用的比较少
BackpressureStrategy.DROP:如果下游阻塞处理不过来了,将最近的值直接丢弃
BackpressureStrategy.LATEST:如果下游阻塞处理不过来了,那么只保留最新的值
3.使用
3.1 简单使用
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
emitter.onNext("send1");
Log.e(TAG, "Observable3 subscribe onNext ");
emitter.onComplete();
Log.e(TAG, "Observable3 subscribe onComplete ");
}
}).map(new Function<String, Integer>() {
@Override
public Integer apply(String s) throws Throwable {
if ("send1".equals(s)) {
return 0;
}else {
return 1;
}
}
}).observeOn(AndroidSchedulers.mainThread()) //前台线程展示
.subscribeOn(Schedulers.io()) //后台线程处理数据
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG, "Observable3 onSubscribe = " + d.isDisposed());
}
@Override
public void onNext(@NonNull Integer s) {
Log.e(TAG, "Observable3 onNext = " + s);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "Observable3 onError = " + e.getMessage());
}
@Override
public void onComplete() {
Log.e(TAG, "Observable3 onComplete");
}
});
上述就是使用最简单的使用了,使用create创建被订阅者,被订阅者内部逻辑放在io线程中subscribeOn(Schedulers.io())
,使用map中间进行转换,将字符串send1转换成数字0进行输出,subscribe订阅订阅者,放在AndroidSchedulers.mainThread()
线程中展示,一般线程都是这么操作。
运行之后结果是:
流程就是先订阅,然后被订阅者发送事件,订阅者接收事件,最后完成。
3.2背压模式
Flowable.create(new FlowableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull FlowableEmitter<String> emitter) throws Throwable {
for (int i=0;i<1000;i++){
emitter.onNext("send"+i);
Log.e(TAG, "Observable4 subscribe onNext = " + i);
}
// emitter.onComplete();
// Log.e(TAG, "Observable4 subscribe onComplete = ");
}
}, BackpressureStrategy.ERROR).map(new Function<String, Integer>() {
@Override
public Integer apply(String s) throws Throwable {
Log.e(TAG, "Observable4 map apply = "+s);
if (s.contains("send")){
return 0;
}
return 1;
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Integer>() {
@Override
public void onSubscribe(Subscription s) {
Log.e(TAG, "Observable4 onSubscribe = " + s.toString());
}
@Override
public void onNext(@NonNull Integer s) {
Log.e(TAG, "Observable4 onNext = " + s);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "Observable4 onError = " + e.getMessage());
}
@Override
public void onComplete() {
Log.e(TAG, "Observable4 onComplete");
}
});
上述就是使用背压模式进行数据处理,过程基本都是一样的,只是订阅者和被订阅者更换类,添加了背压策略。这里使用的是Error,所以就会在订阅者的onError中报错,但是不会崩溃。
如果使用BUFFER策略,就不会报错,只是会执行完。
如果使用MISSING策略,同样会报错,但是被订阅者在子线程中还是会发射完: