1.RxJava是什么?
Reactive Extensions(简称 ReactiveX) 是对响应式编程理念的一个实现。
它最初是由微软的一个团队所开发的响应式扩展库(Reactive Extensions libraray,Rx),随后越来流行,目前已经支持了几乎全部的流行编程语言。
RxJava是java语言的扩展库。此外还有RxPy等等
响应式编程:一种关注于数据流(data streams)和变化传递(propagation of change)的异步编程方式。
其核心思想是观察者模式,上游的数据发生变化,下游能够及时感知到这些变化。
比如:
int a = 1;
int b = a + 1;
Log.d("log" , b); // 2
a ++;
b = a + 1;
Log.d("log" , b); // 3
这种写法是很常见的命令式编程。
可以看出,我们希望b永远比a大1,但是由于语言限制,只能每次都做一次赋值。
我们就会希望存在某种方式,可以让我们只用构建一次a与b的关系,之后a的变化,不需要更多的操作b都可以知道。
这种思想就是响应式编程的思想。
2.RxJava有什么
rxjava实现响应式主要依赖四个基本接口,他们成对使用。
一个简单示例:
第一步:初始化 Observable/Flowable
Observable observable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(@NonNull ObservableEmitter e) {
//处理网络请求或其他业务无关逻辑
e.onNext(1);
e.onNext(2);
e.onNext(3);
e.onComplete();
e.onNext(4);
}
});
第二步:初始化 Observer/Subscriber
Observer observer = new Observer() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull Integer integer) {
// do sth
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
}
第三步:建立订阅关系
observable.subscribe(observer);
上游(被观察者)是生产数据的,比如网络请求/调用三方库生成数据,数据产生一般来说我们的业务上不关心。
下游(观察者)是接受数据的,一般这里就是我们业务相关的处理了。比如收到网络返回的值后刷新界面等。
虽然说RxJava在android平台的实现借鉴了观察者模式。但是Observable 不保存Observer,一个Observable一次发布只能对应一个Observer,
严格上讲不是观察者模式的实现。
被观察者的比较
在最新的RxJava中提供了五种场景的被观察者的基础类,它们之间的功能和主要区别如下:
Flowable: 多个流,响应式流和背压
Observable: 多个流,无背压
Single: 只有一个元素或者错误的流
Completable: 没有任何元素,只有一个完成和错误信号的流
Maybe: 没有任何元素或者只有一个元素或者只有一个错误的流
3.RxJava可以做什么
框架的核心是在Observable的类上,基本上它的操作都可以链式调用。
1.创建操作
1. 基础创建:create 创建一个新的Observable
2. 快速创建:
- just 快速创建被观察者对象并直接发送传入的事件(最多10个事件)
- fromArray/fromIterable
类似just,只不过是可变参数的方法,没有事件数限制
Observable.fromArray( 1, 2, 3, 4, 5 );
Observable.fromIterable(new ArrayList();
- empty/error/never
直接发送Complete事件,或onError事件,或不发送任何事件
3. 延迟创建:
- defer:
Observable observable = Observable.defer(
(new Callable>() {
@Override
public ObservableSource extends Integer> call() {
return Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) {
Log.d(TAG, "defer subscribe: a = " + a + " b = " + b);
emitter.onNext(a + b);
}
});
}
}));
observable.subscribe(a -> Log.d(TAG, "defer accept 1: " + a));
observable.subscribe(a -> Log.d(TAG, "defer accept 2: " + a));
每次用户订阅的时候会创建一个新的obversable,不订阅就不创建
- timer: 一定时间后发送一个0L
- interval/intervalRange: 每隔指定时间就发送一个Long(从0开始每次递增1)
- range/rangeLong:
Observable.range(5, 10).subscribe(i -> System.out.println("1: " + i));
产生一个从5开始的连续10个整数构成的序列
4. 重复发送:
- repeat/repeatUntil:
Observable.fromArray(1, 2, 3, 4, 5).repeat(5)
.subscribe(a -> Log.d(TAG, "accept create: " + a));
重复发5次12345
- repeatWhen(Observable another)
当另一个被观察者发射数据时,重发本观察者的数据
2.变换操作
-
map/cast 将上游发送的数据转换成另一类数据
-
flatMap系列:上游发送一整个序列过来,逐个发送给下游
-
buffer 打包操作
-
scan
将相邻两个原始的结果运算后发给下游
-
groupBy
3.过滤操作
-
filter
- ofType filter的条件是类型判断
Observable.fromArray(1, "2", 3, "w", 5).ofType(Integer.class)
-
distinct 过滤重复
- 其他过滤方式:除了上述根据条件过滤的方式,框架还提供了根据时间、位置过滤事件的接口
4.组合操作
-
startWith & startWithArray
-
merge/mergeArray :合并操作
Observable.merge(Observable.range(1,5), Observable.range(6,10)).subscribe(o)
-
concat & concatArray & concatEager :链接操作
5.其他操作
- 线程切换:subscribeOn & observeOn
subscribeOn 指定被观察者运行的线程
observeOn 指定观察者接收数据的进程
这里,库封装了线程池,对外提供线程调度器:- Schedulers.io():
代表适用于io操作的调度器,增长或缩减来自适应的线程池,通常用于网络、读写文件等io密集型的操作。重点需要注意的是线程池是无限制的,大量的I/O调度操作将创建许多个线程并占用内存。 - Schedulers.computation():
计算工作默认的调度器,代表CPU计算密集型的操作,与I/O操作无关。它也是许多RxJava方法,比如buffer(),debounce(),delay(),interval(),sample(),skip(),的默认调度器。 - Schedulers.newThread():代表一个常规的新线程。
- Schedulers.immediate():
这个调度器允许你立即在当前线程执行你指定的工作。它是timeout(),timeInterval()以及timestamp()方法默认的调度器。 - Schedulers.trampoline():
这个调度器有一个队列,会把任务入队延时操作。它是repeat()和retry()方法默认的调度器。 - AndroidSchedulers.mainThread() RxAndroid库提供的用来指代Android的主线程
- Schedulers.io():
- 错误处理:
- 超时 timeout
- Error处理 onErrorReturn等
- 重试 retry :根据得到的error重试subscribe方法
4 总结
优点
- 上下游处理分离,两边各自关注各自的关键逻辑,可以很好的解耦。两部分也可以由不同的开发人员同时开发。
- 支持背压等系列流式操作
- 可以和Retrofit、Gson等框架完美结合
缺点
- 支持的操作过多,学习成本大
- 小厂开发用到的开源库不多,多数场景下都是自己维护自己的架构,强行切换RxJava成本高,不一定会让结构更好
- Google官方推荐不适用RxJava,推荐直接使用Livedata