Android响应式编程——RxJava3框架的使用(二)

文章导航

Android响应式编程——RxJava3框架的使用(一)

Android响应式编程——RxJava3框架的使用(二)

Android响应式编程——RxJava3框架的使用(三)

Android响应式编程——RxJava3框架的使用(四)

RxJava常用操作符

1.创建操作符

  1. create():创建最简单的事件流
  2. from():创建事件流,可发送不同类型的数据流
  3. just():创建事件流,可发送多个参数的数据流
  4. defer():创建事件流,可缓存可激活事件流
  5. range():创建事件流,可发送范围内的数据流
  6. interval():创建延时重复的事件流
  7. repeat():创建可重复次数的事件流
  8. timer():创建一次延时的事件流

补充:interval()、timer()、delay()的区别

  • interval():用于创建事件流,周期性重复发送
  • timer():用于创建事件流,延时发送一次
  • delay():用于事件流中,可以延时某次事件流的发送

1.1 create

create在之前的文章中就有使用,最原生的创建Observable的方式,onNext/onComplete/onError可完全自由控制。
在这里插入图片描述
Observable最原始的创建方式,创建出一个最简单的事件流,可以使用发射器发射特定的数据类型

public static void main(String[] args) {
    Observable
            .create(new ObservableOnSubscribe<Integer>() {
                @Override
                public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
                    for (int i = 1; i < 5; i++) {
                        e.onNext(i);
                    }
                    e.onComplete();
                }
            })
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            }, new Consumer<Throwable>() {
                @Override
                public void accept(Throwable throwable) throws Exception {

                }
            }, new Action() {
                @Override
                public void run() throws Exception {
                    System.out.println("onComplete");
                }
            });
}

1.2 from

在这里插入图片描述fromArray方法参数为可变长参数,因此既可传数组,也可传多个参数

        String[] strings = {"a", "b", "c"};
        Observable.fromArray(strings);
        Observable.fromArray("a", "b", "c");
        Observable.fromArray(1, 2, 3, 4);

fromIterable方法参数为实现Iterable接口的类,一般为JDK中的List/Map/Set等集合类

        String[] strings = {"aa12", "bb34", "cc56"};
        List<String> listString = Arrays.asList(strings);
        Observable.fromIterable(listString);

1.3 just

在这里插入图片描述
just重载了多个参数数量不同的方法,最大可带10个参数,just同样是调用的fromArray方法;

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 5)
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            });
}

1.4 defer

在这里插入图片描述defer与just的区别是,just是直接将发射当前的数据流,而defer会等到订阅的时候,才会去执行它的call()回调,再去发射当前的数据流。复杂点的理解就是:defer操作符是将一组数据流在原有的事件流基础上缓存一个新的事件流,直到有人订阅的时候,才会创建它缓存的事件流

    i = 10;
    Observable<Object> defer = Observable.defer(new Callable<ObservableSource<?>>() {
        @Override
        public ObservableSource<?> call() throws Exception {
            //缓存新的事件流
            return Observable.just(i);
        }
    });

    defer.subscribe(new Consumer<Object>() {
        @Override
        public void accept(Object o) throws Exception {
            System.out.println("onNext=" + (int) o);
        }
    });
    
	//修改发射的数据
    i = 20;

    defer.subscribe(new Consumer<Object>() {
        @Override
        public void accept(Object o) throws Exception {
            System.out.println("onNext=" + (int) o);
        }
    });

输出

onNext=10
onNext=20

1.5 range

在这里插入图片描述range操作符发射一个范围内的有序整数数据流,你可以指定范围的起始和长度

public static void main(String[] args) {
    Observable.range(10, 4)
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            });
}

		//发送从10开始的整数,发送4个(发到13)
        Observable.range(10, 4);
        //发送从10开始的长整型数,发送6个(发到15)
        Observable.rangeLong(10, 6);

1.6 interval

在这里插入图片描述interval用于定时发送

		//每3秒发个自增整数
        Observable.interval(3, TimeUnit.SECONDS);
        //初始延时1秒,每3秒发一个自增整数
        Observable.interval(1, 3, TimeUnit.SECONDS);
		//初始延时2秒,后每1秒发一个从10开始的整数,发5个(发到14)停止
        Observable.intervalRange(10, 5, 2, 1, TimeUnit.SECONDS);

1.7 repeat

在这里插入图片描述repeat操作符可以重复发送指定次数的某个事件流,repeat操作符默认在trampoline调度器上执行,repeat默认重复次数为Long.MAX_VALUE,可使用重载方法指定次数以及使用repeatUntil指定条件

		//一直重复
        Observable.fromArray(1, 2, 3, 4).repeat();
        //重复发送5次
        Observable.fromArray(1, 2, 3, 4).repeat(5);
        //重复发送直到符合条件时停止重复
        Observable.fromArray(1, 2, 3, 4).repeatUntil(new BooleanSupplier() {
			@Override
			public boolean getAsBoolean() throws Exception {
				//自定判断条件,为true即可停止,默认为false
				return false;
			}
		});

1.8 timer

在这里插入图片描述
timer用于延时发送

		//延时3秒后,发送一个整数0
        Observable.timer(3, TimeUnit.SECONDS);

2.转换操作符

  1. map():对数据流的类型进行转换
  2. flatMap():对数据流的类型进行包装成另一个数据流
  3. scan():对上一轮处理过后的数据流进行函数处理
  4. groupBy():对所有的数据流进行分组
  5. buffer():缓存发射的数据流到一定数量,随后发射出数据流集合
  6. window():缓存发射的数据流到一定数量,随后发射出新的事件流

2.1 map

在这里插入图片描述map利用Function将T转为R

        Observable.just("1", "2", "3").map(new Function<String, Integer>() {
			@Override
			public Integer apply(String s) throws Exception {
				return Integer.valueOf(s) * 10;
			}
		}).subscribe(new Consumer<Integer>() {
			@Override
			public void accept(Integer integer) throws Exception {
                System.out.println(integer);
			}
		});

2.2 flatMap/concatMap

在这里插入图片描述
flatMap操作符将数据流进行类型转换,然后将新的数据流传递给新的事件流进行分发,这里通过模拟请求登录的延时操作进行说明

public void flatMap() {
    Observable.just(new UserParams("hensen", "123456")).flatMap(new Function<UserParams, ObservableSource<String>>() {
        @Override
        public ObservableSource<String> apply(UserParams userParams) throws Exception {
            return Observable.just(userParams.username + "登录成功").delay(2, TimeUnit.SECONDS);
        }
    }).subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            System.out.println(s);
        }
    });
}

public static class UserParams {

    public UserParams(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String username;
    public String password;
}

输出

hensen登录成功

concatMap与flatMap的区别

  • concatMap是有序的

  • flatMap是乱序的

    2.3 scan

    在这里插入图片描述scan操作符会对发射的数据和上一轮发射的数据进行函数处理,并返回的数据供下一轮使用,持续这个过程来产生剩余的数据流。其应用场景有简单的累加计算,判断所有数据的最小值等

public static void main(String[] args) {
    Observable.just(8, 2, 13, 1, 15).scan(new BiFunction<Integer, Integer, Integer>() {
        @Override
        public Integer apply(Integer integer, Integer integer2) throws Exception {
            return integer < integer2 ? integer : integer2;
        }
    })
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer item) throws Exception {
                    System.out.println("onNext=" + item);
                }
            });
}

输出

onNext=8
onNext=2
onNext=2
onNext=1
onNext=1

2.4 groupBy

在这里插入图片描述groupBy操作符可以将发射出来的数据项进行分组,并将分组后的数据项保存在具有key-value映射的事件流中。groupBy具体的分组规则由groupBy操作符传递进来的函数参数Function所决定的,它可以将key和value按照Function的返回值进行分组,返回一个具有分组规则的事件流GroupedObservable,注意这里分组出来的事件流是按照原始事件流的顺序输出的,我们可以通过sorted()对数据项进行排序,然后输出有序的数据流。

public static void main(String[] args) {
    Observable.just("java", "c++", "c", "c#", "javaScript", "Android")
            .groupBy(new Function<String, Character>() {
                @Override
                public Character apply(String s) throws Exception {
                    return s.charAt(0);//按首字母分组
                }
            })
            .subscribe(new Consumer<GroupedObservable<Character, String>>() {
                @Override
                public void accept(final GroupedObservable<Character, String> characterStringGroupedObservable) throws Exception {
                    //排序后,直接订阅输出key和value
                    characterStringGroupedObservable.sorted().subscribe(new Consumer<String>() {
                        @Override
                        public void accept(String s) throws Exception {
                            System.out.println("onNext= key:" + characterStringGroupedObservable.getKey() + " value:" + s);
                        }
                    });
                }
            });
}

输出

onNext= key:A value:Android
onNext= key:c value:c
onNext= key:c value:c#
onNext= key:c value:c++
onNext= key:j value:java
onNext= key:j value:javaScript

2.5 buffer

在这里插入图片描述buffer操作符可以将发射出来的数据流,在给定的缓存池中进行缓存,当缓存池中的数据项溢满时,则将缓存池的数据项进行输出,重复上述过程,直到将发射出来的数据全部发射出去。如果发射出来的数据不够缓存池的大小,则按照当前发射出来的数量进行输出。如果对buffer操作符设置了skip参数,则buffer每次缓存池溢满时,会跳过指定的skip数据项,然后再进行缓存和输出。

Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9)
        .buffer(5).subscribe(new Consumer<List<Integer>>() {
    @Override
    public void accept(List<Integer> integers) throws Exception {
        System.out.println("onNext=" + integers.toString());
    }
});

输出

onNext=[1, 2, 3, 4, 5]
onNext=[6, 7, 8, 9]

2.6 window

在这里插入图片描述window操作符和buffer操作符在功能上实现的效果是一样的,但window操作符最大区别在于同样是缓存一定数量的数据项,window操作符最终发射出来的是新的事件流integerObservable,而buffer操作符发射出来的是新的数据流,也就是说,window操作符发射出来新的事件流中的数据项,还可以经过Rxjava其他操作符进行处理。

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9)
            .window(2, 1).subscribe(new Consumer<Observable<Integer>>() {
        @Override
        public void accept(Observable<Integer> integerObservable) throws Exception {
            integerObservable.subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            });
        }
    });
}

输出

onNext=1
onNext=2
onNext=2
onNext=3
onNext=3
onNext=4
onNext=4
onNext=5
onNext=5
onNext=6
onNext=6
onNext=7
onNext=7
onNext=8
onNext=8
onNext=9
onNext=9

3.过滤操作符

  1. debounce():事件流只发射规定范围时间内的数据项
  2. distinct():事件流只发射不重复的数据项
  3. elementAt():事件流只发射第N个数据项
  4. filter():事件流只发射符合规定函数的数据项
  5. first():事件流只发射第一个数据项
  6. last():事件流只发射最后一项数据项
  7. ignoreElements():忽略事件流的发射,只发射事件流的终止事件
  8. sample():事件流对指定的时间间隔进行数据项的采样
  9. skip():事件流忽略前N个数据项
  10. skipLast():事件流忽略后N个数据项
  11. take():事件流只发射前N个数据项
  12. takeLast():事件流只发射后N个数据项

3.1 debounce

在这里插入图片描述
debounce操作符会去过滤掉发射速率过快的数据项,下面的例子onNext事件可以想象成按钮的点击事件,如果在2秒种内频繁的点击,则其点击事件会被忽略,当i为3的除数的时候,发射的事件的时间会超过规定忽略事件的时间,那么则允许触发点击事件。这就有点像我们频繁点击按钮,但始终只会触发一次点击事件,这样就不会导致重复去响应点击事件

public static void main(String[] args) {
    Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
            for (int i = 0; i < 100; i++) {
                if (i % 3 == 0) {
                    Thread.sleep(3000);
                } else {
                    Thread.sleep(1000);
                }
                emitter.onNext(i);
            }
        }
    }).debounce(2, TimeUnit.SECONDS)
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            });
}

输出

onNext=2
onNext=5
onNext=8
onNext=11
onNext=14
......

3.2 distinct

在这里插入图片描述distinct操作符会过滤重复发送的数据项

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 1, 2, 3).distinct()
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            });
}

输出

onNext=1
onNext=2
onNext=3
onNext=4

3.3 elementAt

在这里插入图片描述elementAt操作符只取指定的角标的事件

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 1, 2, 3).elementAt(0)
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            });
}

输出

onNext=1

3.4 filter

在这里插入图片描述filter操作符可以过滤指定函数的数据项

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 1, 2, 3)
            .filter(new Predicate<Integer>() {
                @Override
                public boolean test(Integer integer) throws Exception {
                    return integer > 2;
                }
            })
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            });
}

输出

onNext=3
onNext=4
onNext=3

3.5 first

在这里插入图片描述first操作符只发射第一项数据项

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 1, 2, 3)
            .first(7)
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            });
}

3.8 last

在这里插入图片描述last操作符只发射最后一项数据

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 1, 2, 3)
            .last(7)
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            });
}

3.7 ignoreElements

在这里插入图片描述ignoreElements操作符不发射任何数据,只发射事件流的终止通知

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 1, 2, 3)
            .ignoreElements()
            .subscribe(new Action() {
                @Override
                public void run() throws Exception {
                    System.out.println("onComplete");
                }
            });
}

输出

onComplete

3.8 sample

在这里插入图片描述sample操作符会在指定的事件内从数据项中采集所需要的数据

public void sample() {
    Observable.interval(1, TimeUnit.SECONDS)
            .sample(2, TimeUnit.SECONDS)
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    System.out.println("onNext=" + aLong);
                }
            });
}

输出

onNext=2
onNext=4
onNext=6
onNext=8

3.9 skip

在这里插入图片描述skip操作符可以忽略事件流发射的前N项数据项,只保留之后的数据

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 5, 6, 7, 8)
            .skip(3)
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer i) throws Exception {
                    System.out.println("onNext=" + i);
                }
            });
}

输出

onNext=4
onNext=5
onNext=6
onNext=7
onNext=8

3.10 skipLast

在这里插入图片描述skipLast操作符可以抑制事件流发射的后N项数据

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 5, 6, 7, 8)
            .skipLast(3)
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer i) throws Exception {
                    System.out.println("onNext=" + i);
                }
            });
}

3.11 take

在这里插入图片描述take操作符可以在事件流中只发射前面的N项数据

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 5, 6, 7, 8)
            .take(3)
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer i) throws Exception {
                    System.out.println("onNext=" + i);
                }
            });
}

输出

onNext=1
onNext=2
onNext=3

3.12takeLast

在这里插入图片描述takeLast操作符事件流只发射数据流的后N项数据项,忽略前面的数据项

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 5, 6, 7, 8)
            .takeLast(3)
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer i) throws Exception {
                    System.out.println("onNext=" + i);
                }
            });
}

4.组合操作符

  1. merge()/concat():无序/有序的合并两个数据流
  2. zip():两个数据流的数据项合并成一个数据流一同发出
  3. startWith():将待合并的数据流放在自身前面一同发出
  4. join():将数据流进行排列组合发出,不过数据流都是有时间期限的
  5. combineLatest():合并最近发射出的数据项成数据流一同发出

4.1 merge/concat

在这里插入图片描述merge操作符可以合并两个事件流,如果在merge操作符上增加延时发送的操作,那么就会导致其发射的数据项是无序的,会跟着发射的时间点进行合并。虽然是将两个事件流合并成一个事件流进行发射,但在最终的一个事件流中,发射出来的却是两次数据流。

public static void main(String[] args) {
    Observable<String> just1 = Observable.just("A", "B", "C", "D", "E");
    Observable<String> just2 = Observable.just("1", "2", "3", "4", "5");

    Observable.merge(just1, just2).subscribe(new Consumer<Serializable>() {
        @Override
        public void accept(Serializable serializable) throws Exception {
            System.out.println("onNext=" + serializable.toString());
        }
    });
}

merge和concat的区别

  • merge():合并后发射的数据项是无序的
  • concat():合并后发射的数据项是有序的

输出

onNext=A
onNext=B
onNext=C
onNext=D
onNext=E
onNext=1
onNext=2
onNext=3
onNext=4
onNext=5

4.2 zip

在这里插入图片描述zip操作符是将两个数据流进行指定的函数规则合并

public static void main(String[] args) {
    Observable<String> just1 = Observable.just("A", "B", "C", "D", "E");
    Observable<String> just2 = Observable.just("1", "2", "3", "4", "5");

    Observable.zip(just1, just2, new BiFunction<String, String, String>() {
        @Override
        public String apply(String s, String s2) throws Exception {
            return s + s2;
        }
    }).subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            System.out.println("onNext=" + s);
        }
    });
}

输出

onNext=A1
onNext=B2
onNext=C3
onNext=D4
onNext=E5

4.3 startWith

在这里插入图片描述
startWith操作符是将另一个数据流合并到原数据流的开头

public static void main(String[] args) {
    Observable<String> just1 = Observable.just("A", "B", "C", "D", "E");
    Observable<String> just2 = Observable.just("1", "2", "3", "4", "5");

    just1.startWith(just2).subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            System.out.println("onNext=" + s);
        }
    });
}

输出

onNext=1
onNext=2
onNext=3
onNext=4
onNext=5
onNext=A
onNext=B
onNext=C
onNext=D
onNext=E

4.4 join

在这里插入图片描述
join操作符是有时间期限的合并操作符

public void join() {
    Observable<String> just1 = Observable.just("A", "B", "C", "D", "E");
    Observable<Long> just2 = Observable.interval(1, TimeUnit.SECONDS);

    just1.join(just2, new Function<String, ObservableSource<Long>>() {
        @Override
        public ObservableSource<Long> apply(String s) throws Exception {
            return Observable.timer(3, TimeUnit.SECONDS);
        }
    }, new Function<Long, ObservableSource<Long>>() {
        @Override
        public ObservableSource<Long> apply(Long l) throws Exception {
            return Observable.timer(8, TimeUnit.SECONDS);
        }
    }, new BiFunction<String, Long, String>() {
        @Override
        public String apply(String s, Long l) throws Exception {
            return s + l;
        }
    }).subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            System.out.println("onNext=" + s);
        }
    });
}

join操作符有三个函数需要设置

  1. 第一个函数:规定just2的过期期限
  2. 第二个函数:规定just1的过期期限
  3. 第三个函数:规定just1和just2的合并规则

由于just2的期限只有3秒的时间,而just2延时1秒发送一次,所以just2只发射了2次,其输出的结果就只能和just2输出的两次进行合并,其输出格式有点类似我们的排列组合

onNext=A0
onNext=B0
onNext=C0
onNext=D0
onNext=E0
onNext=A1
onNext=B1
onNext=C1
onNext=D1
onNext=E1

4.5 combineLatest

在这里插入图片描述conbineLatest操作符会寻找其他事件流最近发射的数据流进行合并

public static String[] str = {"A", "B", "C", "D", "E"};

public void combineLatest() {
    Observable<String> just1 = Observable.interval(1, TimeUnit.SECONDS).map(new Function<Long, String>() {
        @Override
        public String apply(Long aLong) throws Exception {
            return str[(int) (aLong % 5)];
        }
    });
    Observable<Long> just2 = Observable.interval(1, TimeUnit.SECONDS);

    Observable.combineLatest(just1, just2, new BiFunction<String, Long, String>() {
        @Override
        public String apply(String s, Long l) throws Exception {
            return s + l;
        }
    }).subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            System.out.println("onNext=" + s);
        }
    });
}

输出

onNext=A0
onNext=B0
onNext=B1
onNext=C1
onNext=C2
onNext=D2
onNext=D3
onNext=E3
onNext=E4
onNext=A4
onNext=A5

5.错误处理操作符

  1. onErrorReturn():当错误发生时,它会忽略onError的回调且会发射一个新的数据项并回调onCompleted()
  2. onErrorResumeNext():当错误发生时,它会忽略onError的回调且会发射一个新的事件流并回调onCompleted()
  3. onExceptionResumeNext():当错误发生时,如果onError收到的Throwable不是一个Exception,它会回调onError方法,且不会回调备用的事件流,如果onError收到的Throwable是一个Exception,它会回调备用的事件流进行数据的发射
  4. retry():当错误发生时,发射器会重新发射
  5. retryWhen():当错误发生时,根据Tharowble类型决定发射器是否重新发射

5.1 onErrorReturn

在这里插入图片描述onErrorReturn操作符表示当错误发生时,它会忽略onError的回调且会发射一个新的数据项并回调onCompleted()

public static void main(String[] args) {
    Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
            for (int i = 1; i < 5; i++) {
                if(i == 4){
                    e.onError(new Exception("onError crash"));
                }
                e.onNext(i);
            }
        }
    })
            .onErrorReturn(new Function<Throwable, Integer>() {
                @Override
                public Integer apply(Throwable throwable) throws Exception {
                    return -1;
                }
            })
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            }, new Consumer<Throwable>() {
                @Override
                public void accept(Throwable throwable) throws Exception {
                    System.out.println("onError");
                }
            }, new Action() {

                @Override
                public void run() throws Exception {
                    System.out.println("onComplete");
                }
            });
}

输出

onNext=1
onNext=2
onNext=3
onNext=-1
onComplete

5.2 onErrorResumeNext

在这里插入图片描述
onErrorResumeNext操作符表示当错误发生时,它会忽略onError的回调且会发射一个新的事件流并回调onCompleted()

public static void main(String[] args) {
    Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
            for (int i = 1; i < 5; i++) {
                if(i == 4){
                    e.onError(new Exception("onError crash"));
                }
                e.onNext(i);
            }
        }
    })
            .onErrorResumeNext(new Function<Throwable, ObservableSource<? extends Integer>>() {
                @Override
                public ObservableSource<? extends Integer> apply(Throwable throwable) throws Exception {
                    return Observable.just(-1);
                }
            })
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            }, new Consumer<Throwable>() {
                @Override
                public void accept(Throwable throwable) throws Exception {
                    System.out.println("onError");
                }
            }, new Action() {

                @Override
                public void run() throws Exception {
                    System.out.println("onComplete");
                }
            });
}

输出

onNext=1
onNext=2
onNext=3
onNext=-1
onComplete

5.3 onExceptionResumeNext

在这里插入图片描述onExceptionResumeNext操作符表示当错误发生时,如果onError收到的Throwable不是一个Exception,它会回调onError方法,且不会回调备用的事件流,如果onError收到的Throwable是一个Exception,它会回调备用的事件流进行数据的发射

public static void main(String[] args) {
    Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
            for (int i = 1; i < 5; i++) {
                if(i == 4){
                    e.onError(new Exception("onException crash"));
                    //e.onError(new Error("onError crash"));
                }
                e.onNext(i);
            }
        }
    })
            .onExceptionResumeNext(new ObservableSource<Integer>() {
                @Override
                public void subscribe(Observer<? super Integer> observer) {
                    //备用事件流
                    observer.onNext(8);
                }
            })
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            }, new Consumer<Throwable>() {
                @Override
                public void accept(Throwable throwable) throws Exception {
                    System.out.println("onError");
                }
            }, new Action() {

                @Override
                public void run() throws Exception {
                    System.out.println("onComplete");
                }
            });
}

输出

onNext=1
onNext=2
onNext=3
onNext=8

5.4 retry

在这里插入图片描述retry需要触发onError方法才会重复发送数据,重载方法和repeat大同小异

public static void main(String[] args) {
    Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
            for (int i = 1; i < 5; i++) {
                if (i == 4) {
                    e.onError(new Exception("onError crash"));
                }
                e.onNext(i);
            }
        }
    })
            .retry(1)
            .onErrorReturn(new Function<Throwable, Integer>() {
                @Override
                public Integer apply(Throwable throwable) throws Exception {
                    return -1;
                }
            })
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            }, new Consumer<Throwable>() {
                @Override
                public void accept(Throwable throwable) throws Exception {
                    System.out.println("onError");
                }
            }, new Action() {

                @Override
                public void run() throws Exception {
                    System.out.println("onComplete");
                }
            });
}

输出

onNext=1
onNext=2
onNext=3
onNext=1
onNext=2
onNext=3
onNext=-1
onComplete
  • retry():表示重试无限次
  • retry(long times):表示重试指定次数
  • retry(Func predicate):可以根据函数参数中的Throwable类型和重试次数决定本次需不需要重试

5.5 retryWhen

在这里插入图片描述retryWhen操作符和retry操作符相似,区别在于retryWhen将错误Throwable传递给了函数进行处理并产生新的事件流进行处理

private static int retryCount = 0;
private static int maxRetries = 2;

public void retryWhen(){
    Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
            for (int i = 1; i < 5; i++) {
                if (i == 4) {
                    e.onError(new Exception("onError crash"));
                }
                e.onNext(i);
            }
        }
    })
            .retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {
                @Override
                public ObservableSource<?> apply(Observable<Throwable> throwableObservable) throws Exception {
                    return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {
                        @Override
                        public ObservableSource<?> apply(Throwable throwable) throws Exception {
                            if (++retryCount <= maxRetries) {
                                // When this Observable calls onNext, the original Observable will be retried (i.e. re-subscribed).
                                System.out.println("get error, it will try after " + 1 + " seconds, retry count " + retryCount);
                                return Observable.timer(1, TimeUnit.SECONDS);
                            }
                            return Observable.error(throwable);
                        }
                    });
                }
            })
            .onErrorReturn(new Function<Throwable, Integer>() {
                @Override
                public Integer apply(Throwable throwable) throws Exception {
                    return -1;
                }
            })
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            }, new Consumer<Throwable>() {
                @Override
                public void accept(Throwable throwable) throws Exception {
                    System.out.println("onError");
                }
            }, new Action() {

                @Override
                public void run() throws Exception {
                    System.out.println("onComplete");
                }
            });
}

输出

onNext=1
onNext=2
onNext=3
get error, it will try after 1 seconds, retry count 1
onNext=1
onNext=2
onNext=3
get error, it will try after 1 seconds, retry count 2
onNext=1
onNext=2
onNext=3
onNext=-1
onComplete

6.辅助性操作符

  1. delay():延迟事件发射的数据项
  2. do():监听事件流的生命周期
  3. materialize()/dematerialize():对事件流进行装箱/拆箱
  4. serialize():同步事件流的发射
  5. timeInterval():对事件流增加时间间隔
  6. timeout():对事件流增加限定时间
  7. timestamp():对事件流增加时间戳
  8. using():对事件流增加一次性的资源
  9. to():对数据流中的数据项进行集合的转换

6.1 delay

在这里插入图片描述delay用于延时发送,区别在于delay产生泛型Observable,要使用于已经生成的Observable才能起作用

		//延时3秒后,发送"1""2""3"
        Observable.just("1","2","3").delay(3,TimeUnit.SECONDS);

6.2 do

在这里插入图片描述do操作符可以监听整个事件流的生命周期,do操作符分为多个类型,而且每个类型的作用都不同

  • doOnNext():接收每次发送的数据项
  • doOnEach():接收每次发送的数据项
  • doOnSubscribe():当事件流被订阅时被调用
  • doOnDispose():当事件流被释放时被调用
  • doOnComplete():当事件流被正常终止时被调用
  • doOnError():当事件流被异常终止时被调用
  • doOnTerminate():当事件流被终止之前被调用,无论正常终止还是异常终止都会调用
  • doFinally():当事件流被终止之后被调用,无论正常终止还是异常终止都会调用
public static void main(String[] args) {
    Observable.just(1, 2, 3)
            .doOnNext(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("doOnNext");
                }
            })
            .doOnEach(new Consumer<Notification<Integer>>() {
                @Override
                public void accept(Notification<Integer> integerNotification) throws Exception {
                    System.out.println("doOnEach");
                }
            })
            .doOnSubscribe(new Consumer<Disposable>() {
                @Override
                public void accept(Disposable disposable) throws Exception {
                    System.out.println("doOnSubscribe");
                }
            })
            .doOnDispose(new Action() {
                @Override
                public void run() throws Exception {
                    System.out.println("doOnDispose");
                }
            })
            .doOnTerminate(new Action() {
                @Override
                public void run() throws Exception {
                    System.out.println("doOnTerminate");
                }
            })
            .doOnError(new Consumer<Throwable>() {
                @Override
                public void accept(Throwable throwable) throws Exception {
                    System.out.println("doOnError");
                }
            })
            .doOnComplete(new Action() {
                @Override
                public void run() throws Exception {
                    System.out.println("doOnComplete");
                }
            })
            .doFinally(new Action() {
                @Override
                public void run() throws Exception {
                    System.out.println("doFinally");
                }
            })
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            });
}

输出

doOnSubscribe
doOnNext
doOnEach
onNext=1
doOnNext
doOnEach
onNext=2
doOnNext
doOnEach
onNext=3
doOnEach
doOnTerminate
doOnComplete
doFinally

6.3 materialize/dematerialize

在这里插入图片描述在这里插入图片描述materialize操作符将发射出的数据项转换成为一个Notification对象,而dematerialize操作符则是跟materialize操作符相反,这两个操作符有点类似我们Java对象的装箱和拆箱功能

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 5).materialize()
            .subscribe(new Consumer<Notification<Integer>>() {
                @Override
                public void accept(Notification<Integer> integerNotification) throws Exception {
                    System.out.println("onNext=" + integerNotification.getValue());
                }
            });
    
    Observable.just(1, 2, 3, 4, 5).materialize().dematerialize()
            .subscribe(new Consumer<Object>() {
                @Override
                public void accept(Object object) throws Exception {
                    System.out.println("onNext=" + object.toString());
                }
            });
}

输出

onNext=1
onNext=2
onNext=3
onNext=4
onNext=5
onNext=null
onNext=1
onNext=2
onNext=3
onNext=4
onNext=5

输出的时候,materialize会输出多个null,是因为null的事件为onCompleted事件,而dematerialize把onCompleted事件给去掉了,这个原因也可以从图片中看出来

6.4 serialize

在这里插入图片描述serialize操作符可以将异步执行的事件流进行同步操作,直到事件流结束

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 5).serialize()
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            });
}

输出

onNext=1
onNext=2
onNext=3
onNext=4
onNext=5

6.5 timeInterval

在这里插入图片描述timeInterval操作符可以将发射的数据项转换为带有时间间隔的数据项

public void timeInterval(){
    Observable.interval(2, TimeUnit.SECONDS).timeInterval(TimeUnit.SECONDS)
            .subscribe(new Consumer<Timed<Long>>() {
                @Override
                public void accept(Timed<Long> longTimed) throws Exception {
                    System.out.println("onNext=" + longTimed.value() + " timeInterval=" + longTimed.time());
                }
            });
}

输出

onNext=0 timeInterval=2
onNext=1 timeInterval=2
onNext=2 timeInterval=2
onNext=3 timeInterval=2
onNext=4 timeInterval=2

6.6 timeout

在这里插入图片描述timeout操作符表示当发射的数据项超过了规定的限制时间,则发射onError事件,这里直接让程序超过规定的限制时间

public void timeOut(){
    Observable.interval(2, TimeUnit.SECONDS).timeout(1, TimeUnit.SECONDS)
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    System.out.println("onNext=" + aLong);
                }
            }, new Consumer<Throwable>() {
                @Override
                public void accept(Throwable throwable) throws Exception {
                    System.out.println("onError");
                }
            });
}

输出

onError

6.7 timestamp

在这里插入图片描述
timestamp操作符会给每个发射的数据项带上时间戳

public void timeStamp() {
    Observable.interval(2, TimeUnit.SECONDS).timestamp(TimeUnit.MILLISECONDS)
            .subscribe(new Consumer<Timed<Long>>() {
                @Override
                public void accept(Timed<Long> longTimed) throws Exception {
                    System.out.println("onNext=" + longTimed.value() + " timeInterval=" + longTimed.time());

                }
            });
}

6.8 using

在这里插入图片描述using操作符可以让你的事件流存在一次性的数据项,即用完就将资源释放掉

using操作符接受三个参数:

  • 一个用户创建一次性资源的工厂函数
  • 一个用于创建一次性事件的工厂函数
  • 一个用于释放资源的函数
public static class UserBean {
    String name;
    int age;

    public UserBean(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public static void main(String[] args) {
    Observable.using(new Callable<UserBean>() {
        @Override
        public UserBean call() throws Exception {
            //从网络中获取某个对象
            return new UserBean("吴彦祖", 22);
        }
    }, new Function<UserBean, ObservableSource<?>>() {
        @Override
        public ObservableSource<?> apply(UserBean userBean) throws Exception {
            //拿出你想要的资源
            return Observable.just(userBean.name);
        }
    }, new Consumer<UserBean>() {
        @Override
        public void accept(UserBean userBean) throws Exception {
            //释放对象
            userBean = null;
        }
    }).subscribe(new Consumer<Object>() {
        @Override
        public void accept(Object o) throws Exception {
            System.out.println("onNext=" + o.toString());
        }
    });
}

输出

onNext=吴彦祖

6.9 to

在这里插入图片描述
to操作符可以将数据流中的数据项进行集合的转换,to操作符分为多个类型,而且每个类型的作用都不同

  • toList():转换成List类型的集合
  • toMap():转换成Map类型的集合
  • toMultimap():转换成一对多(即<A类型,List<B类型>>)的Map类型的集合
  • toSortedList():转换成具有排序的List类型的集合
public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 5).toList()
            .subscribe(new Consumer<List<Integer>>() {
                @Override
                public void accept(List<Integer> integers) throws Exception {
                    System.out.println("onNext=" + integers.toString());
                }
            });
}

输出

onNext=[1, 2, 3, 4, 5]

7.条件和布尔操作符

  1. all():对所有数据项进行校验
  2. contains():所有数据项是否包含指定数据项
  3. amb():多个事件流中,只发射最先发出的事件流
  4. defaultIfEmpty():如果数据流为空则发射默认数据项
  5. sequenceEqual():判断两个数据流是否完全相等
  6. skipUntil():当两个事件流发射时,第一个事件流的数据项会等到第二个事件流开始发射时才进行发射
  7. skipWhile():当发射的数据流达到某种条件时,才开始发射剩余所有数据项
  8. takeUntil():当两个事件流发射时,第一个事件流的数据项会等到第二个事件流开始发射时终止发射
  9. takeWhile():当发射的数据流达到某种条件时,才停止发射剩余所有数据项

7.1 all

在这里插入图片描述all操作符表示对所有数据项进行校验,如果所有都通过则返回true,否则返回false

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 5)
            .all(new Predicate<Integer>() {
                @Override
                public boolean test(Integer integer) throws Exception {
                    return integer > 0;
                }
            })
            .subscribe(new Consumer<Boolean>() {
                @Override
                public void accept(Boolean aBoolean) throws Exception {
                    System.out.println("onNext=" + aBoolean);
                }
            });
}

7.2 contains

在这里插入图片描述contains操作符表示事件流中发射的数据项当中是否包含有指定的数据项,如果包含则返回true,否则返回false

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 5)
            .contains(2)
            .subscribe(new Consumer<Boolean>() {
                @Override
                public void accept(Boolean aBoolean) throws Exception {
                    System.out.println("onNext=" + aBoolean);
                }
            });
}

7.3 amb

在这里插入图片描述amb操作符在多个事件流中只发射最先发出数据的事件流

public void amb(){
    List<Observable<Integer>> list = new ArrayList<>();
    list.add(Observable.just(1, 2, 3).delay(3, TimeUnit.SECONDS));
    list.add(Observable.just(4, 5, 6).delay(2, TimeUnit.SECONDS));
    list.add(Observable.just(7, 8, 9).delay(1, TimeUnit.SECONDS));

    Observable.amb(list)
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            });
}

输出

onNext=7
onNext=8
onNext=9

7.4 defaultIfEmpty

在这里插入图片描述defaultIfEmpty操作符会在事件流没有发射任何数据时,发射一个指定的默认值

public static void main(String[] args) {
    Observable.empty()
            .defaultIfEmpty(-1)
            .subscribe(new Consumer<Object>() {
                @Override
                public void accept(Object o) throws Exception {
                    System.out.println("onNext=" + o.toString());
                }
            });
}

输出

onNext=-1

7.5 sequenceEqual

在这里插入图片描述sequenceEqual操作符可以判断两个数据流是否完全相等

public static void main(String[] args) {
    Observable<Integer> just1 = Observable.just(1, 2, 3);
    Observable<Integer> just2 = Observable.just(1, 2, 3);

    Observable.sequenceEqual(just1, just2)
            .subscribe(new Consumer<Boolean>() {
                @Override
                public void accept(Boolean aBoolean) throws Exception {
                    System.out.println("onNext=" + aBoolean);
                }
            });
}

7.6 skipUntil

在这里插入图片描述skipUtils操作符是在两个事件流发射的时候,第一个事件流会等到第二个事件流开始发射的时候,第一个事件流才开始发射出数据项,它会忽略之前发射过的数据项

public void skipUntil(){
    Observable<Long> just1 = Observable.interval(1, TimeUnit.SECONDS);
    Observable<Integer> just2 = Observable.just(8).delay(3, TimeUnit.SECONDS);

    just1.skipUntil(just2)
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    System.out.println("onNext=" + aLong);
                }
            });
}

7.7 skipWhile

在这里插入图片描述

skipWhile操作符是在一个事件流中,从第一项数据项开始判断是否符合某个特定条件,如果判断值返回true,则不发射该数据项,继续从下一个数据项执行同样的判断,直到某个数据项的判断值返回false时,则终止判断,发射剩余的所有数据项。需要注意的是,这里只要一次判断为false则后面的所有数据项都不判断

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 5)
            .skipWhile(new Predicate<Integer>() {
                @Override
                public boolean test(Integer integer) throws Exception {
                    return integer < 3;
                }
            })
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            });
}

输出

onNext=3
onNext=4
onNext=5

7.8 takeUntil

在这里插入图片描述takeUntil操作符跟skipUntil类似,skip表示跳过的意思,而take表示取值的意思,takeUntil操作符是在两个事件流发射的时候,第一个事件流会等到第二个事件流开始发射的时候,第一个事件流停止发射数据项,它会忽略之后的数据项

public void takeUntil(){
    Observable<Long> just1 = Observable.interval(1, TimeUnit.SECONDS);
    Observable<Integer> just2 = Observable.just(8).delay(3, TimeUnit.SECONDS);

    just1.takeUntil(just2)
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    System.out.println("onNext=" + aLong);
                }
            });
}

输出

onNext=0
onNext=1

7.9 takeWhile

在这里插入图片描述takeWhile操作符是在一个事件流中,从第一项数据项开始判断是否符合某个特定条件,如果判断值返回true,则发射该数据项,继续从下一个数据项执行同样的判断,直到某个数据项的判断值返回false时,则终止判断,且剩余的所有数据项不会发射。需要注意的是,这里只要一次判断为false则后面的所有数据项都不判断

public static void main(String[] args) {
    Observable.just(1, 2, 3, 4, 0)
            .takeWhile(new Predicate<Integer>() {
                @Override
                public boolean test(Integer integer) throws Exception {
                    return integer < 3;
                }
            })
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("onNext=" + integer);
                }
            });
}

输出

onNext=1
onNext=2

8.数学运算及聚合操作符

数学运算操作符的使用需要在gradle中添加rxjava-math的依赖

implementation 'io.reactivex:rxjava-math:1.0.0'
  1. average():求所有数据项的平均值
  2. max/min():求所有数据项的最大或最小值
  3. sum():求所有数据项的总和
  4. reduce():对上一轮处理过后的数据流进行函数处理,只返回最后的结果
  5. collect():对上一轮处理过后的数据流进行函数处理,可改变原始的数据结构

8.1 reduce

在这里插入图片描述
reduce操作符跟scan操作符是一样的,会对发射的数据和上一轮发射的数据进行函数处理,并返回的数据供下一轮使用,持续这个过程来产生剩余的数据流。reduce与scan的唯一区别在于reduce只输出最后的结果,而scan会输出每一次的结果,这点从图片中也能看出来

public static void main(String[] args) {
    Observable.just(8, 2, 13, 1, 15).reduce(new BiFunction<Integer, Integer, Integer>() {
        @Override
        public Integer apply(Integer integer, Integer integer2) throws Exception {
            return integer < integer2 ? integer : integer2;
        }
    })
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer item) throws Exception {
                    System.out.println("onNext=" + item);
                }
            });
}

输出

onNext=1

8.2 collect

在这里插入图片描述
collect操作符跟reduce操作符类似,只不过collect增加了一个可改变数据结构的函数供我们处理

public static void main(String[] args) {
    Observable.just(8, 2, 13, 1, 15).collect(new Callable<String>() {
        @Override
        public String call() throws Exception {
            return "A";
        }
    }, new BiConsumer<String, Integer>() {
        @Override
        public void accept(String s, Integer integer) throws Exception {
            System.out.println("onNext=" + s + "  " + integer);
        }
    }).subscribe(new BiConsumer<String, Throwable>() {
        @Override
        public void accept(String s, Throwable throwable) throws Exception {
            System.out.println("onNext2=" + s);
        }
    });
}

输出

onNext=A  8
onNext=A  2
onNext=A  13
onNext=A  1
onNext=A  15
onNext2=A

9.连接操作符

  1. publish():将普通的事件流转换成可连接的事件流
  2. connect():将可连接的事件流进行连接并发射数据
  3. refCount():将可连接的事件流转换成普通的事件流
  4. replay():缓存可连接的事件流中的所有数据项

9.1 publish

在这里插入图片描述publish操作符是将普通的事件流转化成可连接的事件流ConnectableObservable,它与普通的事件流不一样,ConnectableObservable在没有调用connect()进行连接的情况下,事件流是不会发射数据的

public static void main(String[] args) {
    ConnectableObservable<Integer> connectableObservable = Observable.just(1, 2, 3, 4, 5).publish();

    connectableObservable.subscribe(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            System.out.println("onNext=" + integer);
        }
    });
}

9.2 connect

connect操作符是将可连接的事件流进行连接并开始发射数据。这个方法需要注意的是,connect操作符必须在所有事件流被订阅后才开始发射数据。如果放在subscribe之前的话,则订阅者是无法收到数据的。如果后面还有订阅者将订阅此次事件流,则会丢失已经调用了connect后,发射出去的数据项

public static void main(String[] args) {
    ConnectableObservable<Integer> connectableObservable = Observable.just(1, 2, 3, 4, 5).publish();

    connectableObservable.subscribe(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            System.out.println("onNext=" + integer);
        }
    });
    
    connectableObservable.connect();
}

输出

onNext=1
onNext=2
onNext=3
onNext=4
onNext=5

9.3 refCount

在这里插入图片描述refCount操作符可以将可连接的事件流转换成普通的事件流

public static void main(String[] args) {
    ConnectableObservable<Integer> connectableObservable = Observable.just(1, 2, 3, 4, 5).publish();

    connectableObservable.refCount().subscribe(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            System.out.println("onNext=" + integer);
        }
    });
}

输出

onNext=1
onNext=2
onNext=3
onNext=4
onNext=5

9.4 replay

在这里插入图片描述

replay操作符将弥补connect操作符的缺陷,由于connect会让后面进行订阅的订阅者丢失之前发射出去的数据项,所以使用replay操作符可以将发射出去的数据项进行缓存,这样使得后面的订阅者都可以获得完整的数据项。这里需要注意的是,replay操作符不能和publish操作符同时使用,否则将不会发射数据。例子中,读者可以将replay操作符换成publish操作符,这时候的输出就会丢失前2秒发射的数据项

public void replay(){
    ConnectableObservable<Long> connectableObservable = Observable.interval(1, TimeUnit.SECONDS).replay();
    connectableObservable.connect();

    connectableObservable.delaySubscription(3, TimeUnit.SECONDS)
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    System.out.println("onNext=" + aLong);
                }
            });
}

输出

onNext=0
onNext=1
onNext=2
onNext=3
onNext=4
onNext=5
......

下一篇:Android响应式编程——RxJava3框架的使用(三)](https://blog.csdn.net/weixin_42046829/article/details/104891414)

发布了63 篇原创文章 · 获赞 1 · 访问量 2101

猜你喜欢

转载自blog.csdn.net/weixin_42046829/article/details/104836592