Rxjava2基础概念和操作符

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

结论

  1. 在 onComplete();/onError 发射完成之后,下游不再接收上游的事件
  2. 已经发射了onComplete(), 再发射onError RxJava会报错,不允许
  3. 先发射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; // 重试
    }
})

架构师系列文章一览

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT小瓯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值