在之前使用Retrofit的时候,简答介绍了一下RxJava
的使用,通过CallAdapterFactory()
使得RxJava
适配Android
平台,也就是RxAndroid
这个概念,在之前接触到这里的时候,我说过,RxJava最大的优点,就是多样的操作符,可以得到我们想要的数据类型,返回到UI层,所以从这节开始,我就介绍一下RxJava中,那些最常用的操作符。
implementation 'io.reactivex.rxjava2:rxjava:2.1.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.7.1'
1、如何理解操作符
在使用RxJava时,我们最常用的三个对象:Observable(被观察者)、Observer(观察者)、subscribe(订阅),通过链式调用,Observable就可以看做是数据发射源,源源不断的数据从上游留到下游,观察者在下游接收这些数据,对于一些原始数据类型,并不是UI层想要的,需要进行数据转换,才会更新在UI层,这个时候,操作符的作用就来了。
RxJava给我们提供了丰富的操作符类型:
Creating 创建操作 - Create
/Defer
/From
/Just
/Start
/Repeat
/Range
Transforming 变换操作 - Buffer
/Window
/Map
/FlatMap
/GroupBy
/Scan
Filtering 过滤操作 - Debounce
/Distinct
/Filter
/Sample
/Skip
/Take
Combining 结合操作 - And
/StartWith
/Join
/Merge
/Switch
/Zip
Error Handling 错误处理 - Catch
/Retry
Utility 辅助操作 - Delay
/Do
/ObserveOn
/SubscribeOn
/Subscribe
Conditional 条件和布尔操作 - All
/Amb
/Contains
/SkipUntil
/TakeUntil
Mathematical 算术和聚合操作 - Average
/Concat
/Count
/Max
/Min
/Sum
/Reduce
Async 异步操作 - Start
/ToAsync
/StartFuture
/FromAction
/FromCallable
/RunAsync
Connect 连接操作 - Connect
/Publish
/RefCount
/Replay
Convert 转换操作 - ToFuture
/ToList
/ToIterable
/ToMap
/toMultiMap
Blocking 阻塞操作 - ForEach
/First
/Last
/MostRecent
/Next
/Single
/Latest
String 字符串操作 - ByLine
/Decode
/Encode
/From
/Join
/Split
/StringConcat
那么接下来,我就逐一介绍一下各类操作符的用法。
1、创建类操作符
(1)create
这个是最常见的、最常用的操作符,用来创建一个Observable对象
(2)just
just操作符其实就是一个数据发射器,创建一个发射指定数据的Observable。
Observable.just(1,2,3)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println("得到的值:"+integer);
}
});
结果:
得到的值:1
得到的值:2
得到的值:3
结果就是将1,2,3(指定的数据)依次发射出来,在下游接收数据。
如果是list集合,会是什么样的呢?
List<Integer> list =new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
Observable.just(list)
.subscribe(new Consumer<List<Integer>>() {
@Override
public void accept(List<Integer> integers) throws Exception {
System.out.println("得到的数据:"+integers);
}
});
结果:
得到的数据:[1, 2, 3]
可以看到的是,并没有将数据一个一个地发射出来,而是形成一个数组,如果想要一个一个地输出,需要使用下面的from
操作符。
(3)from
其实和just一样,都是将一组数据发射出来,但是from操作符可以将一个相同类型数据的数组发射出来。
—fromArray
:发射数组
Integer[] items = {1,2,3,4,5};
Observable.fromArray(items)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println("得到的值为:"+integer);
}
});
结果:
得到的值为:1
得到的值为:2
得到的值为:3
得到的值为:4
得到的值为:5
----fromIterable
:发送集合数据
List<Integer> list =new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
Observable.fromIterable(list)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println("得到的值为:"+integer);
}
});
结果:
得到的值为:1
得到的值为:2
得到的值为:3
(4)defer
defer操作符,指的是在观察者订阅之后,才会创建Observable对象。
Observable<Object> observale = Observable.defer(new Callable<ObservableSource<?>>() {
@Override
public ObservableSource<?> call() throws Exception {
return Observable.just(str);
}
});
observale.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
System.out.println("得到的数据:"+s);
}
});
结果:
得到的数据:null
将str赋值,str = “123”
结果:
得到的数据:123
也就是说在观察者订阅之后,才创建了观察者对象,然后把数据输出,如果是just
、from
操作符,在调用这些操作之后就会创建被观察者对象,不管之后是否订阅。
(5)Range、repeat
重复几次发射一个范围的数据。
Observable.range(1,5).repeat(2)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println("得到的数据:"+integer);
}
});
结果:
得到的数据:1
得到的数据:2
得到的数据:3
得到的数据:4
得到的数据:5
得到的数据:1
得到的数据:2
得到的数据:3
得到的数据:4
得到的数据:5
2、变换类操作符
(1)map
map通常是用来做数据变换,例如将上游的数据都加上一个字符串然后输出。
List<Integer> list =new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
Observable.fromIterable(list)
.map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return integer+"晚上好";
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
System.out.println("转换后的数据:"+s);
}
});
结果:
转换后的数据:1晚上好
转换后的数据:2晚上好
转换后的数据:3晚上好
map就是将整型数据转换为字符串,最终输出。
(2)flatMap
跟map不一样的是,flatMap
通常是用来做事件的变换,还是拿上一个例子说明:
List<Integer> list =new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
Observable.fromIterable(list)
.flatMap(new Function<Integer, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(Integer integer) throws Exception {
List<String> list = new ArrayList<>();
list.add(integer+"晚上好");
return Observable.fromIterable(list);
}
}).subscribe(new Consumer<Object>() {
@Override
public void accept(Object o) throws Exception {
System.out.println("得到的数据:"+o);
}
});
结果:
得到的数据:1晚上好
得到的数据:2晚上好
得到的数据:3晚上好
数据都是一样的,但是性质完全不同;在map中,是将数据类型转换后,直接return到下游输出;但是FlatMap
return的不是数据,而是新创建的一个Observable
对象,将新转换的数据源发射出来,也就是说flatMap是将一个Observable对象转换为了另一个Observable对象,所以利用这个性质,可以做嵌套网络请求。
此外concatMap
同样也是用于事件变换,只不过concatMap对于顺序有要求。
(3)scan
Scan
操作符对原始Observable
发射的第一项数据应用一个函数,然后将那个函数的结果作为自己的第一项数据发射。它将函数的结果同第二项数据一起填充给这个函数来产生它自己的第二项数据。它持续进行这个过程来产生剩余的数据序列。
List<Integer> list =new ArrayList<>();
list.add(1);
list.add(5);
list.add(3);
Observable.fromIterable(list)
.scan(new BiFunction<Integer, Integer, Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) throws Exception {
return integer + integer2;
}
}).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println("接收的数据:"+integer);
}
});
结果:
接收的数据:1
接收的数据:6
接收的数据:9
看到结果你们应该就懂了:将原始Observable发射的第一个数据1应用于函数,1+0 = 1输出,然后将结果和发射的第个2数据应用于函数 1+5 = 6输出,然后将结果和发射的第3个数据应用于函数 6 +3 = 9.
(4)groupBy
将数据进行分组
List<Integer> list =new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
Observable.fromIterable(list)
.groupBy(new Function<Integer, Integer>() {
@Override
public Integer apply(Integer integer) throws Exception {
return integer % 2;
}
}).subscribe(new Consumer<GroupedObservable<Integer, Integer>>() {
@Override
public void accept(GroupedObservable<Integer, Integer> group) throws Exception {
group.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println("分组:"+group.getKey()+" 接收到的数据:"+integer);
}
});
}
});
通过groupBy
来设计分组规则,这里是将数据分为2组,然后得到一个GroupedObservable
(分组被观察者对象),然后订阅后得到分组的结果。