文章目录
RxJava概念与观察者模式
RxJava的上游与下游
流程整理 1
// 上游 Observable 被观察者
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
// 发射
Log.d(TAG, "上游 subscribe: 开始发射..."); // todo 2
emitter.onNext("RxJavaStudy");
emitter.onComplete(); // 发射完成 // todo 4
// 上游的最后log才会打印
Log.d(TAG, "上游 subscribe: 发射完成");
}
}).subscribe(
// 下游 Observer 观察者
new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
// 弹出 加载框 ....
Log.d(TAG, "上游和下游订阅成功 onSubscribe 1"); // todo 1
}
@Override
public void onNext(String s) {
Log.d(TAG, "下游接收 onNext: " + s); // todo 3
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
// 隐藏加载框
Log.d(TAG, "下游接收完成 onComplete"); // todo 5 只有接收完成之后,上游的最后log才会打印
}
});
/**
* 结论:
* D/MainActivity: 上游和下游订阅成功 onSubscribe 1
* D/MainActivity: 上游 subscribe: 开始发射...
* D/MainActivity: 下游接收 onNext: RxJavaStudy
* D/MainActivity: 下游接收完成 onComplete
* D/MainActivity: 上游 subscribe: 发射完成
*/
流程整理 2
结论
- 在 onComplete();/onError 发射完成之后,下游不再接收上游的事件
- 已经发射了onComplete(), 再发射onError RxJava会报错,不允许
- 先发射onError,再onComplete();,不会报错, 有问题(onComplete不会接收到了)
流程整理 3
切断下游
Rxjava创建型操作符
create
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
// 上游发射的
e.onNext("A"); // 使用者自己发射
}
})
just
Observable.just("A", "B")
just:发射单一对象
fromArray
String[] strings = {"张三", "李四", "王五"};
Observable.fromArray(strings)
fromArray:发射数集对象
empty
// 上游无法指定 事件类型
Observable.empty() // 内部一定会只调用 发射 onComplete 完毕事件
empty:下游默认是Object,无法发出有值事件,只会发射onComplete
range
// 上游 range内部会去发射
// Observable.range(1, 8) // 1 2 3 4 5 6 7 8 从1开始加 数量共8个
range:累加
Rxjava变换型操作符
上游 -------> 变换操作(往右边流向的时候,进行变换) ----------> 下游
map
1.map 把上一层Int Int变换String 观察者String类型。
// 在上游和下游之间 变换
.map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
// 1
Log.d(TAG, "map1 apply: " + integer);
return "【" + integer + "】";
}
})
flatMap
2.flatMap 把上一层Int Int变换ObservableSource{还可以再次发射多次事件} 观察者String类型。 不排序的
// 变换操作符
.flatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(final Integer integer) throws Exception {
// integer == 111
// ObservableSource == 可以再次手动发送事件
return Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext(integer + "flatMap变换操作符");
e.onNext(integer + "flatMap变换操作符");
e.onNext(integer + "flatMap变换操作符");
}
});
}
})
// 下游的泛型是String类型的
// 体现 flatMap 变换 操作符 是不排序的
.flatMap(new Function<String, ObservableSource<?>>() { // ? 通配符 默认Object
@Override
public ObservableSource<?> apply(String s) throws Exception {
List<String> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
list.add(s + " 下标:" + (1 + i));
}
return Observable.fromIterable(list).delay(5, TimeUnit.SECONDS); // 创建型操作符,创建被观察者
}
})
// 下游的泛型是Object类型的
concatMap
3.concatMap 把上一层Int Int变换ObservableSource{还可以再次发射多次事件} 观察者Bitmap类型。 排序的
// 体现 concatMap 变换操作符 排序的
.concatMap(new Function<String, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(String s) throws Exception {
List<String> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
list.add(s + " 下标:" + (1 + i));
}
return Observable.fromIterable(list).delay(5, TimeUnit.SECONDS); // 创建型操作符,创建被观察者
}
})
groupBy
4.groupBy 把上一层Int Int变换String(高端配置电脑) 观察者GroupedObservable类型 {key=“高端”, 细节再包裹一层}
// 上游
Observable.just(6000, 7000, 8000, 9000, 10000, 14000)
// 变换
.groupBy(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return integer > 8000 ? "高端配置电脑" : "中端配置电脑"; // 分组
}
})
// 订阅
/*.subscribe(new Consumer<String>() { // 下游 使用 groupBy
@Override
public void accept(String string) throws Exception {
}
});*/
// 使用groupBy下游是 有标准的
.subscribe(new Consumer<GroupedObservable<String, Integer>>() {
@Override
public void accept(final GroupedObservable<String, Integer> groupedObservable) throws Exception {
Log.d(TAG, "accept: " + groupedObservable.getKey());
// 以上还不能把信息给打印全面,只是拿到了,分组的key
// 输出细节,还需要再包裹一层
// 细节 GroupedObservable 被观察者
groupedObservable.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.d(TAG, "accept: 类别:" + groupedObservable.getKey() + " 价格:" + integer);
}
});
}
});
buffer
5.buffer 100个事件 Integer .buffer(20) 观察者List==五个集合。
很多的数据,不想全部一起发射出去,分批次,先缓存到Buffer
// 上游
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
for (int i = 0; i < 100; i++) {
e.onNext(i);
}
e.onComplete();
}
})
// 变换 buffer
.buffer(20)
.subscribe(new Consumer<List<Integer>>() {
@Override
public void accept(List<Integer> integer) throws Exception {
Log.d(TAG, "accept: " + integer);
}
});
RxJava过滤型操作符
上游 -------> 过滤操作(往右边流向的时候,进行过滤) ----------> 下游
filter 过滤
1.filter 如果是false全部都发射给下游,如果是true,全部都不发射给下游。
.filter(new Predicate<String>() {
@Override
public boolean test(String s) throws Exception {
// return true; // 不去过滤,继续传给下游
// return false; // 过滤掉,continue下一条
if ("三鹿".equals(s)) {
return false;
}
return true;
}
})
// 除了“三鹿”,其他都会被发射到下游
take 过滤操作符
take :只有再定时器运行基础上 加入take过滤操作符,才有take过滤操作符的价值。
Observable.interval(2, TimeUnit.SECONDS)// 每2s发射一次
// 增加过滤操作符,停止定时器
.take(8) // 执行次数达到8 停止下来
.subscribe(new Consumer<Long>() { // 下游
@Override
public void accept(Long aLong) throws Exception {
Log.d(TAG, "accept: " + aLong);
}
});
distinct 过滤重复事件
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
e.onNext(1);
e.onNext(1);
e.onNext(2);
e.onNext(3);
e.onNext(4);
e.onNext(4);
e.onComplete();
}
})
.distinct() // 过滤重复 发射的事件
.subscribe(new Consumer<Integer>() { // 下游 观察者
@Override
public void accept(Integer integer) throws Exception {
Log.d(TAG, "accept: " + integer); // 事件不重复
}
});
// 打印出1234,重复的被过滤掉了。
elementAt 操作符
4.elementAl 指定发射事件内容,如果没找到,则发射默认的事件。
// 上游
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("九阴真经");
e.onNext("九阳真经");
e.onNext("易筋经");
e.onNext("神照经");
e.onComplete();
}
})
// 过滤操作符
.elementAt(100, "默认经") // 指定下标输出 事件
// 订阅
.subscribe(new Consumer<String>() { // 下游
@Override
public void accept(String s) throws Exception {
Log.d(TAG, "accept: " + s);
}
});
// 这里是指定第100个事件,肯定不存在,所以输出默认事件
RxJava条件型操作符
如果使用了条件操作符,下一层,接收的类型 就是条件类型(Boolean)
All操作符
全部满足条件,则为true
Observable.just(v1, v2, v3, v4) // RxJava 2.X 之后 不能传递null,否则会报错
.all(new Predicate<String>() {
@Override
public boolean test(String s) throws Exception {
return !s.equals("cc"); // 如果s不等于cc,就是true
}
})
.subscribe(new Consumer<Boolean>() { // 下游 观察者
@Override
public void accept(Boolean s) throws Exception {
Log.d(TAG, "accept: " + s);
}
});
contains操作符
包含,则为true
Observable.just("JavaSE", "JavaEE", "JavaME", "Android", "iOS", "Rect.js", "NDK")
.contains("C") // 是否包含了 Android,条件是否满足
.subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean s) throws Exception {
Log.d(TAG, "accept: " + s);
}
});
any操作符
任意一个满足条件,为true
Observable.just("JavaSE", "JavaEE", "JavaME", "Android", "iOS", "Rect.js", "NDK")
.any(new Predicate<String>() {
@Override
public boolean test(String s) throws Exception {
return s.equals("Android");
}
}) // 是否包含了 Android,条件是否满足
.subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean s) throws Exception {
Log.d(TAG, "accept: " + s);
}
});
RxJava合并型操作符
startWait操作符
先执行 startWait括号里面的被观察者
// 上游
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
// todo 2
e.onNext(1);
e.onNext(2);
e.onNext(3);
e.onComplete();
}
})
.startWith(Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
// todo 1
e.onNext(10000);
e.onNext(20000);
e.onNext(30000);
e.onComplete();
}
}))
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.d(TAG, "accept: " + integer);
}
});
// D/MainActivity6: accept: 10000
// D/MainActivity6: accept: 20000
// D/MainActivity6: accept: 30000
// D/MainActivity6: accept: 1
// D/MainActivity6: accept: 2
// D/MainActivity6: accept: 3
concatWith操作符
后执行 concatWait括号里面的被观察者
// 例子同上者startWith操作符,输出相反
concat操作符
是按照顺序依次执行 最多四个被观察者进行合并
// 上游 被观察者
Observable.concat(
Observable.just("1") // todo 1
,
Observable.just("2") // todo 2
,
Observable.just("3") // todo 3
,
Observable.create(new ObservableOnSubscribe<String>() { // todo 4
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("4");
e.onComplete();
}
})
)
.subscribe(new Consumer<String>() { // 下游 观察者
@Override
public void accept(String s) throws Exception {
Log.d(TAG, "accept: " + s);
}
});
// 1234
merge操作符
并列执行的,(演示并列的执行,所以学了intervalRange) 最多四个被观察者进行合并
// 被观察者1
Observable observable1 = Observable.intervalRange(1, 5, 1,2, TimeUnit.SECONDS);
// 被观察者2
Observable observable2 = Observable.intervalRange(6, 5, 1,2, TimeUnit.SECONDS); // 6 7 8 9 10
// 被观察者3
Observable observable13 = Observable.intervalRange(11, 5, 1,2, TimeUnit.SECONDS); // 11 12 13 14 15
// 上游
Observable.merge(observable1, observable2, observable13) // 合并成一个 被观察者
.subscribe(new Consumer() {
@Override
public void accept(Object o) throws Exception {
// 被观察者1 1
// 被观察者2 6
// 被观察者3 11
Log.d(TAG, "accept: " + o);
}
});
// 输出:
accept: 1
accept: 6
accept: 11
accept: 2
accept: 7
accept: 12
accept: 3
accept: 8
accept: 13
accept: 4
accept: 9
accept: 14
accept: 5
accept: 10
accept: 15
zip操作符
需要对应关系 需要对应,如果不对应,会被忽略的, 最多9个被观察者 进行合并
/**
* zip 合并操作符:合并的被观察者发射的事件,需要对应
* 需求:考试 课程 == 分数
* @param view
*/
public void r05(View view) {
// 课程 被观察者
Observable observable1 = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("英语"); // String
e.onNext("数学");
e.onNext("政治");
e.onNext("物理"); // 被忽略
e.onComplete();
}
});
// 分数 被观察者
Observable observable2 = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
e.onNext(85); // Integer
e.onNext(90);
e.onNext(96);
e.onComplete();
}
});
// 9 被观察者
Observable.zip(observable1, observable2, new BiFunction<String, Integer, StringBuffer>() { // T1 String, T2 Integer, R StringBuffer
@Override
public StringBuffer apply(String string, Integer integer) throws Exception {
return new StringBuffer().append("课程" + string).append("==").append(integer+"");
}
})
.subscribe(/*new Consumer() {
@Override
public void accept(Object o) throws Exception {
Log.d(TAG, "最终考试的结果 accept: " + o);
}
}*/
new Observer() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "onSubscribe: 准备进入考场,考试了....");
}
@Override
public void onNext(Object o) {
Log.d(TAG, "onNext: 考试结果输出 " + o);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete: 考试全部完毕");
}
}
);
}
// 输出:
onSubscribe: 准备进入考场,考试了....
onNext: 考试结果输出 课程英语==85
onNext: 考试结果输出 课程数学==90
onNext: 考试结果输出 课程政治==96
onComplete: 考试全部完毕
RxJava异常处理操作符
RxJava中是不标准的报错方式:throw new xxxException(“我要报错了”);但是也能被onErrorReturn,onErrorResumeNext,onExceptionResumeNext等操作符拦截到。
RxJava中标准的报错方式:e.onError(XXX);
throw new xxxError方式都不能拦截,程序直接奔溃。
onErrorReturn
能够接收到e.onError(Error/Exception)/throw new xxxException.
特点:能够打印异常详情,会给下游一个标记。
// 上游 被观察者
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
for (int i = 0; i < 100; i++) {
if (i == 5) {
// RxJava中是不标准的
// throw new IllegalAccessException("我要报错了");
// RxJava标准的
e.onError(new IllegalAccessException("我要报错了")); // 发射异常事件
}
e.onNext(i);
}
e.onComplete();
}
})
// 在上游 和 下游之间 添加异常操作符
.onErrorReturn(new Function<Throwable, Integer>() {
@Override
public Integer apply(Throwable throwable) throws Exception {
// 处理,纪录,异常,通知给下一层
Log.d(TAG, "onErrorReturn: " + throwable.getMessage());
return 400; // 400代表有错误,给下一层,目前 下游 观察者
}
})
.subscribe(new Observer<Integer>() { // 完整版 下游 观察者
@Override
public void onSubscribe(Disposable d) {
}
// 如果使用了 异常操作符 onNext: 400
@Override
public void onNext(Integer integer) {
Log.d(TAG, "onNext: " + integer); // 400
}
// 如果不使用 异常操作符 onError
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete: ");
}
});
onErrorResumeNext
能够接收到e.onError(Error/Exception)/throw new xxxException.
特点:可以重新返回一个被观察者,发射多次事件
.onErrorResumeNext(new Function<Throwable, ObservableSource<? extends Integer>>() {
@Override
public ObservableSource<? extends Integer> apply(Throwable throwable) throws Exception {
// onErrorResumeNext 返回的是 被观察者,所以再多次发射给 下游 给 观察者接收
return Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
e.onNext(400);
e.onNext(400);
e.onNext(400);
e.onNext(400);
e.onNext(400);
e.onNext(400);
e.onComplete();
}
});
}
})
onExceptionResumeNext
只能够接收到e.onError(Exception)/throw new xxxException,不接收Error。
同样可以返回一个被观察者。
// 上游
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
for (int i = 0; i < 100; i++) {
if (i == 5) {
/* throw new 其他Exception("错了");
throw new IllegalAccessException("错了");*/
throw new Exception("错了");
// e.onError(new IllegalAccessException("错了")); // 异常事件
} else {
e.onNext(i);
}
}
e.onComplete();
}
})
// 在上游和下游中间 增加 异常操作符
.onExceptionResumeNext(new ObservableSource<Integer>() {
@Override
public void subscribe(Observer<? super Integer> observer) {
observer.onNext(404); // 可以让程序 不崩溃的
}
})
retry
return false; 代表不去重试 return true; 不停的重试, 演示二 重试次数, 演示三 打印重试了多少次,计数
// todo 演示一
/*.retry(new Predicate<Throwable>() {
@Override
public boolean test(Throwable throwable) throws Exception {
Log.d(TAG, "retry: " + throwable.getMessage());
// return false; // 代表不去重试
return true; // 一直重试,不停的重试
}
})*/
// todo 演示二 重试次数
/*.retry(3, new Predicate<Throwable>() {
@Override
public boolean test(Throwable throwable) throws Exception {
Log.d(TAG, "retry: " + throwable.getMessage());
return true;
}
})*/
// todo 演示三 打印重试了多少次,计数 Throwable + count
.retry(new BiPredicate<Integer, Throwable>() {
@Override
public boolean test(Integer integer, Throwable throwable) throws Exception {
Thread.sleep(2);
Log.d(TAG, "retry: 已经重试了:" + integer + "次 e:" + throwable.getMessage());
return true; // 重试
}
})