学习RxJava,做一下笔记笔记:RxJava(二)
1、描述
- RxJava是一个基于事件流的实现异步操作的库,类似Android的handler、AsyncTask
- 随着程序逻辑变得越来越复杂,它依然能够保持简洁
- RxJava 的异步实现,是通过一种扩展的观察者模式来实现的
- 观察模式可实现回调,采用订阅Subscribe的方式将被观察者Observable与观察者Observer链在一起,实现订阅关系,进行消息事件的通知
2、依赖地址
- RxJava在github的地址 https://github.com/ReactiveX/RxJava现在官网的最新版本就是v 2.1.13
- RxAndroid在github的地址 https://github.com/ReactiveX/RxAndroid现在官网的最新版本就是v 2.0.2
3、简单创建用法与理解
3.1、Observable.create(ObservsbleOnSubscribe)的使用
/**
* 一、创建 可观察者(Observable ) 以及 生产事件
*
*
* 1. 创建可观察者 Observable 对象,可观察的数据类型为String
* 2.create() 是 RxJava 最基本的创造事件序列的方法,还有just(多个数据)、from(数据数组)等
* 3.create(ObservableOnSubscribe)此处一个ObservableOnSubscribe对象参数
* 4.当 Observable 被订阅时,OnSubscribe 的 call() 方法会自动被调用,即事件序列就会依照设定依次被触发
* 也就是只有被订阅时,事件才会发送
*/
Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Exception {
/**
* 1.重写的subscribe(),自定义需要发送的事件
* 2. 通过 ObservableEmitter类对象,事件发射器,产生事件并通知观察者
*/
emitter.onNext("test1");
emitter.onNext("test2");
emitter.onNext("test3");
emitter.onNext("test4");
emitter.onComplete();
//=====================================>>>>>>>>>>关注①
//emitter.onNext("test1");
//emitter.onNext("test2");
//emitter.onNext("test3");
//emitter.onComplete();
//emitter.onNext("test4");
// =====================================>>>>>>>>>>关注②
// emitter.onNext("test1");
// emitter.onNext("test2");
// emitter.onError(new Throwable("onError"));
// emitter.onNext("test3");
// emitter.onComplete();
// emitter.onNext("test4");
}
});
/**
*
* 二、创建 观察者 (Observer )以及 自定义响应事件的行为
*
*
* 1. 创建观察者 (Observer )对象,观察数据对象为String
* 2. 自动复写对应事件的方法 从而 响应对应的事件
*
*
*/
Observer<String> observer=new Observer<String>() {
// 观察者接收事件之前,默认最先调用复写 onSubscribe()这个方法
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.d("TAG", "开始subscribe连接,接收上游可观察者(Observable)的事件");
}
/**
* 当可观察者生产Next事件 这里的 观察者接收到时,会调用该复写这个方法 进行事件响应,可接收多个Next事件,
* 直到接收到上游可观察者onComplete/onError事件,其中onComplete/onError事件是唯一的,两者之间是互斥的
*/
@Override
public void onNext(@NonNull String s) {
Log.d("TAG", "接收到Next事件=="+s);
}
/**
* 当可观察者生产Error事件并且 观察者接收到时,会调用该复写这个方法 进行响应
* 当观察者接收到可观察者发过来的onError事件时,观察者不再接收事件了,但 可观察者可以继续发送事件
* onError事件与onComplete事件时互斥的,两者只能有其一
*/
@Override
public void onError(@NonNull Throwable e) {
Log.d("TAG", "接收到onError事件=="+e.toString());
}
// 当被观察者生产Complete事件& 观察者接收到时,会调用该复写方法 进行响应
@Override
public void onComplete() {
Log.d("TAG", "接收到onComplete事件");
}
};
/**
*
* 三、通过订阅(Subscribe)连接观察者和被观察者
*
* 就好比可观察者为上游的出水水管,观察者为下游接水水管,中间通过Subscribe连接,水就可以通了
* 此时事件可产生,发射,接收
*/
observable.subscribe(observer);
打印的log如下图
关注① 当接收到了onComplete事件后,接收者Observer不再接收后面的事件,但可观察者Observable依然会发射事件
打印log结果
关注② 当接收到了onError事件后,接收者Observer不再接收后面的事件,但可观察者Observable依然会发射事件
3.1.1、RxJava的基于事件流的链式使用
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("test1");
emitter.onNext("test2");
emitter.onNext("test3");
emitter.onComplete();
emitter.onError(new Throwable("onError"));
emitter.onNext("test4");
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
//====================================>>>>>>>>>>>关注③
Log.e("TAG", "开始subscribe连接,接收上游可观察者(Observable)的事件");
}
@Override
public void onNext(@NonNull String s) {
Log.e("TAG", "接收到Next事件==" + s);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e("TAG", "接收到onError事件==" + e.toString());
}
@Override
public void onComplete() {
Log.e("TAG", "接收到onComplete事件");
}
});
}
}
打印log结果:接收了 test1、test2、test3和onComplete事件
关注③ 可采用 Disposable.dispose() 切断观察者 与 被观察者 之间的连接
public class MainActivity extends AppCompatActivity {
// 定义Disposable类变量
private Disposable mDisposable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("test1");
emitter.onNext("test2");
emitter.onNext("test3");
emitter.onNext("test4");
emitter.onComplete();
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
// 对Disposable类变量赋值
mDisposable=d;
Log.e("TAG", "开始接收上游可观察者(Observable)的事件");
}
@Override
public void onNext(@NonNull String s) {
Log.e("TAG", "接收到Next事件==" + s);
/**
* 当接收的事件为test2的时候,切断观察者 与 可观察者 之间的连接
* 即观察者 不再继续 接收 可观察者发送的事件,但可观察者还是可以继续发送事件
*
* 就好比可观察者为上游的出水水管,观察者为下游接水水管,中间通过Subscribe连接,现在将两个水管的交接出去掉
* 下游不再可以接收水,上游却可以继续出水
*/
if (s.equals("test2")){
mDisposable.dispose();
}
}
@Override
public void onError(@NonNull Throwable e) {
Log.e("TAG", "接收到onError事件==" + e.toString());
}
@Override
public void onComplete() {
Log.e("TAG", "接收到onComplete事件");
}
});
}
}
Log打印结果:下图可看出,当接收的事件为test2事件后,观察者不再接收后面的事件,连onComplete事件也不再接收,但此时,可观察者依然在继续发送事件
3.2、RxJava其他简单创建用法
3.2.1、just(Object)的使用
1、快速的创建可观察者对象2、直接发送 传入的事件(参数)转化为Observable对象3、最多只能发送10个参数4、将传入的参数依次发射出来5、与 fromXxx( T[] ) / fromXxx( Iterable<? extends T> )用法很接近,参数前者是一个一个的,后者是数组T[]的形式 / Iterable 拆分成的具体对象6、不那么准确的说 fromArray( T[] ) 是 just(Object) 的加强版
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Observable
.just("test1","test2","test3","test4","test5","test6","test7","test8","test9","test10")
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("TAG", "开始接收上游可观察者(Observable)的事件");
}
@Override
public void onNext(@NonNull String s) {
Log.e("TAG", "接收到Next事件==" + s);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e("TAG", "接收到onError事件==" + e.toString());
}
@Override
public void onComplete() {
Log.e("TAG", "接收到onComplete事件");
}
});
}
}
log打印结果:
3.2.2、fromArray( T [ ] )的简单使用
1、 可发送10个以上事件(数组形式)2、不那么准确的说 fromArray( T[] ) 是 just(Object) 的加强版3、与 fromXxx( T[] ) / fromXxx( Iterable<? extends T> )用法很接近4、与 fromIterable( list )用法很接近5、fromArray( T[] ) 的参数是一个数组,将数组中的数据转换为一个个Observable对象6、若传入一个list集合,会直接把list当做一个数据元素,转换为Observable对象发送出去,示例看关注④
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* 设置需要传入的数组
* 快速创建Observable对象
*/
String[] items = {"test1","test2","test3","test4","test5","test6","test7","test8","test9","test10"};
Observable
.fromArray(items)
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("TAG", "开始接收上游可观察者(Observable)的事件");
}
@Override
public void onNext(@NonNull String s) {
Log.e("TAG", "接收到Next事件==" + s.toString());
}
@Override
public void onError(@NonNull Throwable e) {
Log.e("TAG", "接收到onError事件==" + e.toString());
}
@Override
public void onComplete() {
Log.e("TAG", "接收到onComplete事件");
}
});
log打印结果 :
关注④ fromArray() 传入一级list集合,会将这个集合转换为一个Observable对象
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* 设置需要传入的数组
* 快速创建Observable对象
*/
String[] items = {"test1","test2","test3","test4","test5","test6","test7","test8","test9","test10"};
List<String> list=new ArrayList<>();
for (String item:items){
list.add(item);
}
Observable
.fromArray(list)
.subscribe(new Observer<List>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("TAG", "开始接收上游可观察者(Observable)的事件");
}
@Override
public void onNext(@NonNull List s) {
Log.e("TAG", "接收到Next事件==" + s.toString());
}
@Override
public void onError(@NonNull Throwable e) {
Log.e("TAG", "接收到onError事件==" + e.toString());
}
@Override
public void onComplete() {
Log.e("TAG", "接收到onComplete事件");
}
});
下面是参数为 数组 与参数为 list 的log打印结果:
3.2.2.1、额外说明:此处参考文章来自---------Android Rxjava:这是一篇 清晰 & 易懂的Rxjava 入门教程
public final Disposable subscribe() {}
// 表示观察者不对被观察者发送的事件作出任何响应(但可观察者还是可以继续发送事件)
public final Disposable subscribe(Consumer<? super T> onNext) {}
// 表示观察者只对被观察者发送的Next事件作出响应
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError) {}
// 表示观察者只对被观察者发送的Next事件 & Error事件作出响应
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete) {}
// 表示观察者只对被观察者发送的Next事件、Error事件 & Complete事件作出响应
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete, Consumer<? super Disposable> onSubscribe) {}
// 表示观察者只对被观察者发送的Next事件、Error事件 、Complete事件 & onSubscribe事件作出响应
public final void subscribe(Observer<? super T> observer) {}
// 表示观察者对被观察者发送的任何事件都作出响应
3.2.3、fromIterable( list )的简单使用
与前面几个类似,参数是集合list,用法跟前面几个一样,这里就不说明了,需要的话就看前面几个的说明
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* 设置需要传入的数组
* 快速创建Observable对象
*/
String[] items = {"test1","test2","test3","test4","test5","test6","test7","test8","test9","test10"};
List<String> list=new ArrayList<>();
for (String item:items){
list.add(item);
}
Observable
.fromIterable(list)
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("TAG", "开始接收上游可观察者(Observable)的事件");
}
@Override
public void onNext(@NonNull String s) {
Log.e("TAG", "接收到Next事件==" + s);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e("TAG", "接收到onError事件==" + e.toString());
}
@Override
public void onComplete() {
Log.e("TAG", "接收到onComplete事件");
}
});
log打印结果:
3.3、defer()的简单使用
1、在经过了x秒后,需要自动执行y操作 2、每隔x秒后,需要自动执行y操作
##3.4、timer()的简单使用
1、延迟指定时间后,发送1个数值0(Long类型) 2、原理:延迟指定时间后,调用一次 onNext(0) 3、发送一个0,一般用于检测 4、timer操作符默认运行在一个新线程上,既然可以默认也可以自定义,timer(long,TimeUnit,Scheduler)第三个参数可自定义线程,指定timer的运行线程
// 延迟1s后,发送一个long类型数值
Observable.timer(1, TimeUnit.SECONDS)
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
Log.e("TAG", "开始连接");
}
@Override
public void onNext(Long value) {
Log.e("TAG", "onNext=="+ value );
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "接收到onError事件");
}
@Override
public void onComplete() {
Log.e("TAG", "接收到onComplete事件");
}
});
log打印结果:先是打印 开始连接 ,1s后,再打印onNext==0 接收到onComplete事件
3.5、interval()的简单使用
1、快速创建1个被观察者对象(Observable) 2、每隔指定时间 就发送 事件 3、发送的事件序列 = 从0开始、无限递增1的的整数序列
/**
*
* 延迟3s后发送事件,每隔1秒产生1个数字(从0开始递增1,无限个)
*
*
* 参数1 = 第1次延迟时间;
* 参数2 = 间隔时间数字;
* 参数3 = 时间单位;
*/
Observable.interval(3,1,TimeUnit.SECONDS)
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
Log.e("TAG", "开始连接");
}
// 默认最先调用复写的 onSubscribe()
@Override
public void onNext(Long value) {
Log.e("TAG", "接收onNext事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "接收onError事件"+e.toString());
}
@Override
public void onComplete() {
Log.e("TAG", "接收onComplete事件");
}
});
log打印结果:第一次打印开始连接 ,3s后,打印 接收onNext事件0, 之后每隔一秒打印一个接收onNext事件1........N 无限递增
3.6、intervalRange()的简单使用
1、快速创建1个被观察者对象(Observable) 2、每隔指定时间 就发送 事件,可指定发送的数据的数量 3、发送的事件序列 = 从0开始、递增1的的整数序列 4、. 作用类似于interval(),但可指定发送的数据的数量
/**
* 从3开始,一共发送10个事件,第1次延迟2s发送,之后每隔2秒产生1个数字
*
*
* 参数1 = 事件序列起始点
* 参数2 = 事件数量
* 参数3 = 第1次事件延迟发送时间
* 参数4 = 间隔时间数字
* 参数5 = 时间单位
*/
Observable.intervalRange(3,10,2, 1, TimeUnit.SECONDS)
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
Log.e("TAG", " 开始连接");
}
@Override
public void onNext(Long value) {
Log.e("TAG", " 接收onNext事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.e("TAG", " 接收onError事件"+e.toString());
}
@Override
public void onComplete() {
Log.e("TAG", " 接收onComplete事件");
}
});
3.7、range()的简单使用
1、快速创建1个被观察者对象(Observable) 2、连续发送 1个事件序列,可指定范围 3、发送的事件序列 = 从0开始、递增1的的整数序列 4、作用类似于intervalRange(),但区别在于:无延迟发送事件
/**
* 从4开始发送,每次发送事件递增1,一共发送5个事件
*
* 参数1 = 事件序列起始点
* 参数2 = 事件数量
* 注:若设置为负数,则会抛出异常
*/
Observable.range(4,5)
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.e("TAG", "开始连接");
}
@Override
public void onNext(Integer value) {
Log.e("TAG", "接收到了事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "接收onError事件"+e.toString());
}
@Override
public void onComplete() {
Log.e("TAG", "接收onComplete事件");
}
});
log打印结果:
4、RXJava常用操作符的简单使用*
4.1、变换操作符
①、map() 将事件序列中的对象或整个序列进行加工转换,将可观察者要发送的事件转换为任意的类型事件。 ②、Flatmap() ③、ConcatMap() ④、Buffer()
####4.1.1、Map()简单使用
1、说明: 将事件序列中的对象或整个序列进行加工处理,转换成不同的事件或事件序列,不准确的说,就是 传进去的值被转换了,返回的返回值不同了,将可观察者要发送的事件转换为任意的类型事件。
Observable.create(new ObservableOnSubscribe<Integer>() {
// 可观察者发送事件 = 参数为整型 = 1、2、3
@Override
public void subscribe(@NonNull ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
})
// 使用Map变换操作符中的Function函数对可观察者发送的事件
// 进行统一变换:将整型变换成字符串类型
.map(new Function<Integer, String>() {
@Override
public String apply(@NonNull Integer integer) throws Exception {
return "使用 Map变换操作符 将事件" + integer +"的参数从 整型"
+integer + " 变换成 字符串类型" + integer ;
}
})
.subscribe(new Consumer<String>() {
// 观察者接收事件时,是接收到变换后的事件 = 字符串类型
@Override
public void accept(String s) throws Exception {
Log.e("TAG", s);
}
});
log打印结果:
4.1.2、FlatMap()简单使用
- 将被观察者发送的事件序列进行 拆分 & 单独转换,再合并成一个新的事件序列,最后再进行发送
- 无序的将被观察者发送的整个事件序列进行变换
// 采用RxJava基于事件流的链式操作
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onNext(4);
}
// 采用flatMap()变换操作符
}).flatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer integer) throws Exception {
// final List<String> list = new ArrayList<>();
// for (int i = 0; i < 3; i++) {
// list.add("我是事件 " + integer + "拆分后的子事件" + i);
// // 通过flatMap中将可观察者发送的事件序列先进行拆分,再将每个事件转换为一个新的Observable,再发送给出去
// // 最终合并,再发送给被观察者
// return Observable.fromIterable(list);
// }
//这里会生成新的可观察者,然后与观察者订阅,像一种代理机制,通过事件拦截和处理实现事件序列的变换。
return Observable.just("事件 " + integer + " 转换成的子事件 " + "test"+integer);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.e("TAG", s);
}
});
log打印结果:
4.1.3、concatMap()简单使用
- 将被观察者发送的事件序列进行 拆分 & 单独转换,再合并成一个新的事件序列,最后再进行发送
- 无序的将被观察者发送的整个事件序列进行变换
- 用法和flatMap()相同,只是场景不同
- 新合并生成的事件序列顺序是有序的,即 严格按照旧序列发送事件的顺序
// 采用RxJava基于事件流的链式操作
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onNext(4);
}
// 采用concatMap()变换操作符
}).concatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer integer) throws Exception {
// final List<String> list = new ArrayList<>();
// for (int i = 0; i < 3; i++) {
// list.add("我是事件 " + integer + "拆分后的子事件" + i);
// // 通过concatMap中将可观察者发送的事件序列先进行拆分,再将每个事件转换为一个新的Observable,再发送给出去
// // 最终合并,再发送给被观察者
// return Observable.fromIterable(list);
// }
//这里会生成新的可观察者,然后与观察者订阅,像一种代理机制,通过事件拦截和处理实现事件序列的变换。
return Observable.just("事件 " + integer + " 转换成的子事件 " + "test"+integer);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.e("TAG", s);
}
});
log打印结果:
4.1.4、Buffer()简单使用
- 场景:缓存被观察者发送的事件
- 作用:定期从可观察者(Obervable)需要发送的事件中 获取一定数量的事件 & 放到缓存区中,最终发送
// 被观察者 需要发送5个数字
Observable.just(1, 2, 3, 4, 5)
.buffer(3, 1) // 设置缓存区大小 & 步长
// 缓存区大小 = 每次从被观察者中获取的事件数量
// 步长 = 每次获取新事件的数量
.subscribe(new Observer<List<Integer>>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(List<Integer> stringList) {
//
Log.e("TAG", " 缓存区里的事件数量 = " + stringList.size());
for (Integer value : stringList) {
Log.e("TAG", " 接收onNext事件 = " + value);
}
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "接收onError事件" );
}
@Override
public void onComplete() {
Log.e("TAG", "接收Complete事件");
}
});
log打印结果:
4.2、concat() / concatArray()组合多个可观察者
① 组合多个被观察者一起发送数据,合并后 按发送顺序串行执行 ② concat() / concatArray()二者区别:组合被观察者的数量,即concat()组合被观察者数量≤4个,而concatArray()则可>4个
4.2.1、concat()
concat():组合多个被观察者(≤4个)一起发送数据
// 串行执行
Observable
.concat(
Observable.just(1, 2, 3),
Observable.just(4, 5, 6),
Observable.just(7, 8, 9),
Observable.just(10, 11, 12)
)
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
Log.e("TAG", "接收到onNext事件==" + value);
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "接收到onError事件"+e.toString());
}
@Override
public void onComplete() {
Log.e("TAG", "接收到onComplete事件");
}
});
log打印结果:
4.2.2、concatArray()
concat():组合多个被观察者(≤4个)一起发送数据 concatArray():组合多个被观察者一起发送数据(可>4个)
// 串行执行
Observable.concatArray(Observable.just(1, 2, 3),
Observable.just(4, 5, 6),
Observable.just(7, 8, 9),
Observable.just(10, 11, 12),
Observable.just(13, 14, 15))
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
Log.e("TAG", "接收到了事件" + value);
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.e("TAG", "对Complete事件作出响应");
}
});
log打印结果:
4.3、merge() / mergeArray()简单使用
① 组合多个可观察者一起发送数据,合并后 按时间线并行执行 ② 二者区别:组合可观察者的数量,即merge()组合可观察者数量≤4个,而mergeArray()则可>4个 ③ 区别上述concat()操作符:同样是组合多个可观察者一起发送数据,但concat()操作符合并后是按发送顺序串行执行
####4.3.1、merge()简单使用
merge():组合多个可观察者(≤ 4个)一起发送数据
//合并后按照时间线并行执行
Observable.merge(
Observable.intervalRange(0, 3, 1, 1, TimeUnit.SECONDS), // 从0开始发送、共发送3个数据、第1次事件延迟发送时间 = 1s、间隔时间 = 1s
Observable.intervalRange(2, 3, 1, 1, TimeUnit.SECONDS)) // 从2开始发送、共发送3个数据、第1次事件延迟发送时间 = 1s、间隔时间 = 1s
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Long value) {
Log.e("TAG", "接收到onNext事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "接收到onError事件");
}
@Override
public void onComplete() {
Log.e("TAG", "接收到onComplete事件");
}
});
log打印结果:输出结果 = 事件0,事件2 -> 事件1,事件3 -> 事件2,事件4
4.3.2、mergeArray()简单使用
mergeArray():组合多个可观察者(≤ 4个)一起发送数据
Observable.mergeArray(
Observable.intervalRange(0, 3, 1, 1, TimeUnit.SECONDS), // 从0开始发送、共发送3个数据、第1次事件延迟发送时间 = 1s、间隔时间 = 1s
Observable.intervalRange(2, 3, 1, 1, TimeUnit.SECONDS)) // 从2开始发送、共发送3个数据、第1次事件延迟发送时间 = 1s、间隔时间 = 1s
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Long value) {
Log.e("TAG", "mergeArray--接收到onNext事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "mergeArray--接收到onError事件");
}
@Override
public void onComplete() {
Log.e("TAG", "mergeArray--接收到onComplete事件");
}
});
log打印结果:输出结果 = 事件0,事件2 -> 事件1,事件3 -> 事件2,事件4
4.4、concatDelayError() / mergeDelayError()简单使用
- 使用concat()和merge()操作符时,其中1个可观察者发出onError事件,则会马上终止其他可观察者继续发送事件,如果希望onError事件推迟到其他可观察者发送事件结束才再触发发送onError事件,可使用concatDelayError()或者mergeDelayError操作符来解决
Observable.concat( //没有使用concatDelayError()的情况
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onError(new NullPointerException()); // 发送Error事件,因为无使用concatDelayError,所以第2个Observable将不会发送事件
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
}),
Observable.just(4, 5, 6))//没有使用了concatDelayError(),事件4、5、6在onError事件后不再发射
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
Log.e("TAG", " 接收到事件 "+ value );
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "接收到onError事件");
}
@Override
public void onComplete() {
Log.e("TAG", "接收到onComplete事件");
}
});
Observable.concatArrayDelayError(//使用了concatDelayError()的情况
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onError(new NullPointerException()); // 发送Error事件,因为使用了concatDelayError,所以第2个Observable将会发送事件,等发送完毕后,再发送错误事件
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
}),
Observable.just(4, 5, 6))//使用了concatDelayError(),事件4、5、6在onError事件后可以发射
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
Log.e("TAG", "接收到了事件"+ value );
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "接收到了onError事件");
}
@Override
public void onComplete() {
Log.e("TAG", "接收到了onComplete事件");
}
});
log打印结果:下图可知,不适用concatDelayonError时,事件4、5、6没有被发射出来,而使用concatDelayonError时,会发射玩所有事件后,在发射onError事件,就是onError事件被延迟发射了,此情况mergeDelayError雷同,代码就省略了
4.5 合并多个事件Zip()的简单使用
① 该类型的操作符主要是对多个被观察者中的事件进行合并处理 ② 合并 多个被观察者(Observable)发送的事件,生成一个新的事件序列(即组合过后的事件序列),并最终发送 ③ 事件组合方式 = 严格按照原先事件序列 进行对位合并 ④ 最终合并的事件数量 = 多个被观察者(Observable)中数量最少的数量
//创建第1个被观察者
Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
Log.e("TAG", "可观察者1发送了事件 1");
emitter.onNext(1);
// 为了方便展示效果,所以在发送事件后加入2s的延迟
Thread.sleep(2000);
Log.e("TAG", "可观察者1发送了事件2");
emitter.onNext(2);
Thread.sleep(2000);
Log.e("TAG", "可观察者1发送了事件3");
emitter.onNext(3);
Thread.sleep(2000);
Log.e("TAG", "可观察者1发送了事件4");
emitter.onNext(4);
Thread.sleep(2000);
emitter.onComplete();
}
}).subscribeOn(Schedulers.io()); // 设置可观察者1 在线程1中执行
//创建第2个可观察者
Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
Log.e("TAG", "可观察者 2 发送了事件 A ");
emitter.onNext("A");
Thread.sleep(2000);
Log.e("TAG", "可观察者 2 发送了事件 B ");
emitter.onNext("B");
Thread.sleep(2000);
Log.e("TAG", "可观察者 2 发送了事件 C ");
emitter.onNext("C");
Thread.sleep(2000);
Log.e("TAG", "可观察者 2 发送了事件 D ");
emitter.onNext("D");
Thread.sleep(2000);
emitter.onComplete();
}
}).subscribeOn(Schedulers.newThread());// 设置可观察者 2 在 线程2中执行
// 假设不作线程控制,则该两个被观察者会在同一个线程中工作,即发送事件存在先后顺序,而不是同时发送
// 使用zip变换操作符进行事件合并
// 注:创建BiFunction对象传入的3个参数 ==可观察者1的数据类型 可观察者2的数据类型 合并后数据的数据类型
Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {
@Override
public String apply(Integer integer, String string) throws Exception {
return integer + string;
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.e("TAG", "onSubscribe");
}
@Override
public void onNext(String value) {
Log.e("TAG", "最终接收到的事件 = " + value);
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "onError");
}
@Override
public void onComplete() {
Log.e("TAG", "onComplete");
}
});
log打印结果:
4.6 combineLatest()的简单使用
① 当两个Observables中的任何一个发送了数据后,将先发送了数据的Observables 的最新(最后)一个数据 与 另外一个Observable发送的每个数据结合,最终基于该函数的结果发送数据 ② 与Zip()的区别:Zip() = 按个数合并,即1对1合并;CombineLatest() = 按时间合并,即在同一个时间点上合并
Observable.combineLatest(
Observable.just(1L, 2L, 3L), // 第1个发送数据事件的Observable
Observable.intervalRange(0, 3, 2, 2, TimeUnit.SECONDS), // 第2个发送数据事件的Observable:从0开始发送、共发送3个数据、第1次事件延迟发送时间 = 2s、间隔时间 = 2s
new BiFunction<Long, Long, Long>() {
@Override
public Long apply(Long o1, Long o2) throws Exception {
// o1 = 第1个Observable发送的最新(最后)1个数据
// o2 = 第2个Observable发送的每1个数据
Log.e("TAG", "合并的数据是: "+ "第一个 "+o1 + " "+ "第二个 "+o2);
return o1 + o2;
// 合并的逻辑 = 相加
// 即第1个Observable发送的最后1个数据 与 第2个Observable发送的每1个数据进行相加
}
}).subscribe(new Consumer<Long>() {
@Override
public void accept(Long s) throws Exception {
Log.e("TAG", "合并的结果是: "+s);
}
});
log打印结果:
4.7 collect()的简单使用
① 将被观察者Observable发送的数据事件收集到一个数据结构里
Observable.just(1, 2, 3 ,4, 5, 6)
.collect(
// 1. 创建数据结构(容器),用于收集被观察者发送的数据
new Callable<ArrayList<Integer>>() {
@Override
public ArrayList<Integer> call() throws Exception {
return new ArrayList<>();
}
// 2. 对发送的数据进行收集
}, new BiConsumer<ArrayList<Integer>, Integer>() {
@Override
public void accept(ArrayList<Integer> list, Integer integer)
throws Exception {
// 参数说明:list = 容器,integer = 后者数据
list.add(integer);
// 对发送的数据进行收集
}
}).subscribe(new Consumer<ArrayList<Integer>>() {
@Override
public void accept(@NonNull ArrayList<Integer> s) throws Exception {
Log.e("TAG", "本次发送的数据是: "+s);
}
});
log打印结果:
4.8、startWith() / startWithArray()发送事件前追加发送事件
① 在一个被观察者发送事件前,追加发送一些数据 / 一个新的被观察者
//在一个被观察者发送事件前,追加发送一些数据
// 注:追加数据顺序 = 后调用先追加
Observable.just(4, 5, 6)
.startWithArray(1, 2, 3) // 追加多个数据 = startWithArray()
.startWith(0) // 追加单个数据 = startWith()
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
Log.e("TAG", "接收到了事件" + value);
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.e("TAG", "对Complete事件作出响应");
}
});
// 在一个被观察者发送事件前,追加发送被观察者 & 发送数据
// 注:追加数据顺序 = 后调用先追加
Observable.just(4, 5, 6)
.startWith(Observable.just(1, 2, 3))
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer value) {
Log.e("TAG", "接收到了事件" + value);
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.e("TAG", "对Complete事件作出响应");
}
});
log打印结果:
4.9、count()统计发送事件数量
① 统计被观察者发送事件的数量
// 注:返回结果 = Long类型
Observable.just(1, 2, 3, 4)
.count()
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
Log.e("TAG", "发送的事件数量 = "+aLong);
}
});
log打印结果:
4.10、组合 / 合并操作符 总结
5、RxJava的线程控制(切换 / 调度 ):异步操作
① 指定 可观察者 (Observable) / 观察者(Observer) 的工作线程类型 ② 线程控制(也称为调度 / 切换)功能性操作符中的:subscribeOn() 与 observeOn() ③ Observable.subscribeOn(Schedulers.Thread):指定被观察者 发送事件的线程(传入RxJava内置的线程类型) ④ Observable.observeOn(Schedulers.Thread):指定观察者 接收 & 响应事件的线程(传入RxJava内置的线程类型) ⑤ subscribeOn(Schedulers.newThread()) :指定被观察者 生产事件的线程 ⑥ observeOn(AndroidSchedulers.mainThread()) :指定观察者 接收 & 响应事件的线程
5.1 指定可观察者 发射线程 subscribeOn()
若Observable.subscribeOn()多次指定可观察者 生产事件的线程,则只有第一次指定有效,其余的指定线程无效
observable.subscribeOn(Schedulers.newThread()) // 第一次指定被观察者线程 = 新线程
.subscribeOn(AndroidSchedulers.mainThread()) // 第二次指定被观察者线程 = 主线程
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
//被观察者的线程 = 第一次指定的线程 = 新的工作线程,第二次指定的线程(主线程)无效
5.2 指定观察者 接收线程 subscribeOn()
若Observable.observeOn()多次指定观察者 接收 & 响应事件的线程,则每次指定均有效,即每调用一次observeOn(),观察者的线程就会切换一次
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Exception {
}
}).subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()) // 第一次指定观察者线程 = 主线程
.doOnNext(new Consumer<String>() { // 生产事件
@Override
public void accept(String string) throws Exception {
Log.d("TAG", "第一次观察者Observer的工作线程是: " + Thread.currentThread().getName());
}
})
.observeOn(Schedulers.newThread()) // 第二次指定观察者线程 = 新的工作线程
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
}
}); // 生产事件
// 注:
// 1. 整体方法调用顺序:观察者.onSubscribe()> 被观察者.subscribe()> 观察者.doOnNext()>观察者.onNext()>观察者.onComplete()
// 2. 观察者.onSubscribe()固定在主线程进行
log打印结果:
###5.3、背压策略详情请看–关于 RxJava 最友好的文章系列
被观察者发送事件速度远快于观察者的处理速度的情况下,一种告诉上游的被观察者降低发送速度的策略
// 步骤1:创建被观察者 = Flowable
Flowable.create(new FlowableOnSubscribe<Integer>() {
@Override
public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
Log.e("TAG", "发送事件 1");
emitter.onNext(1);
Log.e("TAG", "发送事件 2");
emitter.onNext(2);
Log.e("TAG", "发送事件 3");
emitter.onNext(3);
Log.e("TAG", "发送完成");
emitter.onComplete();
}
}, BackpressureStrategy.ERROR)
.subscribe(new Subscriber<Integer>() {
// 步骤2:创建观察者 = Subscriber & 建立订阅关系
@Override
public void onSubscribe(Subscription s) {
Log.e("TAG", "onSubscribe");
s.request(3);
}
@Override
public void onNext(Integer integer) {
Log.e("TAG", "接收到了事件" + integer);
}
@Override
public void onError(Throwable t) {
Log.e("TAG", "onError: ", t);
}
@Override
public void onComplete() {
Log.e("TAG", "onComplete");
}
});
6、错误处理 使用代码示例与详细讲解
发送事件过程中,遇到错误时的处理机制, 网络请求失败,加载本地,重试等
操作符有
1、 onErrorReturn(): 遇到错误时,发送1个特殊事件 & 正常终止 ①、可捕获在它之前发生的异常
2、 onErrorResumeNext(): 遇到错误时,发送1个新的Observable ①、onErrorResumeNext()拦截的错误 = Throwable;若需拦截Exception请用onExceptionResumeNext() ②、若onErrorResumeNext()拦截的错误 = Exception,则会将错误传递给观察者的onError方法
3、onExceptionResumeNext():遇到错误时,发送1个新的Observable ①、onExceptionResumeNext()拦截的错误 =Exception;若需拦截Throwable请用onErrorResumeNext() ②、若onExceptionResumeNext()拦截的错误 = Throwable,则会将错误传递给观察者的onError方法
4、retry(): 重试,即当出现错误时,让被观察者(Observable)重新发射数据 ①、接收到onError()时,重新订阅 & 发送事件 ②、Throwable 和 Exception都可拦截
5、retryUntil(): 出现错误后,判断是否需要重新发送数据 ①、若需要重新发送 & 持续遇到错误,则持续重试 ②、作用类似于retry(Predicate predicate) ③、具体场景:类似于retry(Predicate predicate),唯一区别:返回 true 则不重新发送数据事件。
6、retryWhen(): 重试,即当出现错误时,让被观察者(Observable)重新发射数据 ①、接收到 onError()时,重新订阅 & 发送事件 ②、Throwable 和 Exception都可拦截
7、retryWhen(): 遇到错误时,将发生的错误传递给一个新的被观察者(Observable),并决定是否需要重新订阅原始被观察者(Observable)& 发送事件
7、重复发送 使用代码示例与详细讲解
重复不断地发送被观察者事件 对应操作符类型:repeat() &repeatWhen()
1、repeat(): 无条件地、重复发送 被观察者事件 ①、具备重载方法,可设置重复创建次数
2、repeatWhen(): 有条件地、重复发送 被观察者事件
①、将原始 Observable 停止发送事件的标识(Complete() / Error())转换成1个 Object类型数据传递给1个新被观察者(Observable),以此决定是否重新订阅 & 发送原来的 Observable ②、若新被观察者(Observable)返回1个Complete / Error事件,则不重新订阅 & 发送原来的 Observable ③、若新被观察者(Observable)返回其余事件时,则重新订阅 & 发送原来的 Observable
8、compose与Transformer 消除重复代码
详细讲解看 1 2 3 这三篇文章
8.1、在使用RXJava与Retrofit请求网络时,遇到过这样的场景,在IO线程请求网络解析数据,接着返回主线程setData、更新View试图,代码如下:
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
8.2、这样肯定是没问题的,但是如果请求网络的次数多了,岂不是每个地方都要写一遍?,并且同时又不想去破环RX的链式结构,怎么办呢,有一个不是唯一的办法,就是使用操作符
RetrofitClient.getData("网络接口URL")
.requestNetData("参数1","参数2")
.compose(CommonTransformer())//自定义ObservableTransformer,完成线程切换
.subscribe(subscriber);
就是用 .compose(schedulersTransformer()) 这一行一行代码就完成了线程切换,代替了.subscribeOn(Schedulers.io()) .unsubscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread())这段代码
8.3、实现ObservableTransformer,完成线程切换,然后使用compose()操作符
/**
* ================================================
* Created by ${chenyuexueer}
* 说明:实现ObservableTransformer,完成线程切换,使用compose()操作符
* ================================================
*/
Observable.Transformer schedulersTransformer() {
return new Observable.Transformer() {
@Override
public Object call(Object observable) {
return ((Observable) observable).subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
};
}
//一行代码搞定,使用情况如下:
//observable.compose (schedulersTransformer()).subscribe(subscriber)
- 笔记所参考文章Android RxJava:组合 / 合并操作符 详细教程Android:这是一篇 清晰 & 易懂的Rxjava 入门教程Android RxJava:最基础的操作符详解 - 创建操作符Android RxJava:图文详解 变换操作符Android RxJava:组合 / 合并操作符 详细教程Android RxJava:功能性操作符 全面讲解给 Android 开发者的 RxJava 详解—作者:抛物线Android RxJava:细说 线程控制(切换 / 调度 )(含Retrofit实例讲解)一个外国大神的Rxjava的demo关于 RxJava 最友好的文章—— RxJava 2.0 全新来袭关于RxJava最友好的文章