这篇文章大概是2017年时整理的,一直在OneNote中存放着,如今创建了个人博客,自然拿了出来。PS:从OneNote中复制出来后格式乱码,整理的我想吐…
介绍
RxJava是Java上一个灵活的、使用可观测序列组成的一个异步的、基于事件的库。
特点:
- 作用:异步
- 模式:观察者模式-本质上是基于回调
- 结构:响应式编程
- 逻辑简洁,可读性高,易维护
- 链式结构的执行顺序
基本流程
- 创建事件资源,也就是被观察者。可以用
Observable.create/just/from
等方法来创建。 - 通过filter/debounce等操作符,进行自定义事件过滤。
- 通过Schedules进行事件发送和订阅的线程控制,也就是
subscribeOn()和observeOn()
。 - 通过map/flatMap/compose等操作符,进行事件的变换
- 调用subscribe进行事件订阅。
- 最后,不要忘了对订阅者生命周期的控制,不用的时候,记得调用
unsubscribe()
,以免引发内存泄漏。
注意:未取消订阅而引起的内存泄漏。在
Activtity.onDestroy()
或不需要继续执行时取消订阅。
CompositeSubscription, 相当于一个Subscription集合,来取消所有订阅。
示例
1 | CompositeSubscription list = new CompositeSubscription(); |
基础知识
Observer和Subscriber的关系
- Observer是观察者,Subscriber也是观察者。
- Subscriber是一个实现了Observer接口的抽象类,对Observer进行了部分扩展,在使用上基本没有区别。
- Subscriber多了发送之前调用的
onStart()
和解除订阅关系的unsubscribe()
方法。 - 在RxJava的subscribe过程中,Observer也总是会先被转换成一个Subscriber再使用。
- RxJava开发过程中一般都使用Subscriber。
RxJava的事件订阅回调
支持以下三种不完整定义的回调,我们可以根据当前需要,传入对应的Action,RxJava会相应的自动创建Subscriber。
observable.subscribe(onNextAction);
observable.subscribe(onNextAction, onErrorAction);
observable.subscribe(onNextAction, onErrorAction, onCompleteAction);
响应式编程
- Observable发出一系列事件,它是事件的产生者。
- Subscriber负责处理事件,它是事件的消费者。
Operator是对Observable发出的事件进行修改和变换 。
注意:若事件从产生到消费不需要其他处理,则可以省略掉中间的Operator,从而流程变为Obsevable -> Subscriber。
Subscriber通常在主线程执行,所以原则上不要去处理太多的事务,而这些复杂的事务处理则交给Operator。
知识点
Scheduler线程控制
默认情况下,RxJava事件产生和消费均在同一个线程中,例如在主线程中调用,那么事件的产生和消费都在主线程,但RxJava可以自由切换线程。
RxJava线程调度器
Schedulers.io();
I/O操作(读写文件、数据库、网络请求等),与 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 效率比 newThread() 更高。值得注意的是,在 io() 下,不要进行大量的计算,以免产生不必要的线程。Schedulers.newThread();
开启新线程操作Schedulers.immediate();
默认指定的线程,也就是当前线程Schedulers.computation();
计算所使用的调度器。这个计算指的是CPU密集型计算,即不会被I/O等操作限制性能的操作,例如图形的计算。这个Scheduler使用的固定的线程池,大小为CPU核数。值得注意的是不要把I/O操作放在computation()中否则I/O操作的等待时间会浪费CPU。
注意:
AndroidSchedulers.mainThread();
是RxJava扩展的Android主线程。- 通过
subscribeOn()
和observeOn()
这两个方法来进行线程调度。
变换操作符(重点)
RxJava可以将发送的事件或事件序列,加工后转换成不用的事件或事件序列。
map操作符
- 是一对一的变换
- 返回的是变换后的对象
- 变换后的对象直接发到Subscriber回调中
flatMap操作符
- 可以适应一对多的变换
- 返回的是一个Observable被观察者对象
- 返回的Observable对象并不是直接发送到Subscriber的回调中,而是重新创建一个Observable对象,并激活这个Observable对象,使之开始发送事件
- flatMap变换后产生的每一个Observable对象发送的事件,最终都汇入同一个Observable,进而发送给Subscriber回调
注意:
- map的返回类型与flatMap返回的Observable事件类型,可以与原来的事件类型一样
- 可以对一个Observable多次使用map和flatMap
- flatMap常常被用于嵌套的异步操作,例如:嵌套网络请求
map操作符代码示例
1 | final ImageView ivLogo = (ImageView) findViewById(R.id.ivLogo); |
flatMap操作符代码示例
1 | final List<Employee> list = new ArrayList<Employee>() { |
from操作符
接收一个集合作为输入,每次输出一个元素给subscriber
注意:若需要执行耗时操作,即使在from中使用
subscribeOn(Schedulers.io())
,仍然是在主线程执行,会造成界面卡顿甚至崩溃。
from操作符代码示例
1 | // 格式:Observable.from(T[] params) |
just操作符
接收一个可变参数作为输入,最终也是生成数组,调用from(),每次输出一个元素给subscriber
just操作符代码示例
1 | // Observable.just(T... params),params的个数为1 ~ 10 |
filter操作符
条件过滤,用于去除不符合条件的事件
filter操作符代码示例
1 | Observable.from(new Integer[]{1, 2, 3, 4, 5}) |
take操作符
最多保留的事件数
doOnNext操作符
在处理下一个事件前要做的事
take和doOnNext操作符代码示例
1 | Observable.from(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}) |
输出结果:
1
2
3
4
5
6
7 > hahcode = 2
> number = 2
> hahcode = 4
> number = 4
> hahcode = 6
> number = 6
>
debounce操作符
过滤在指定的时间间隔之间的事件,接收一个事件后将在指定时间间隔后开始接收事件
debounce操作符代码示例
1 | Observable.create(new Observable.OnSubscribe<Integer>() { |
merge操作符
用于合并两个Observable为一个Observable
格式:
1 | Observable.merge(Observable1, Observable2) |
concat操作符
顺序的执行多个Ovservable,个数为1—9(示例见first操作符)
compose操作符
类似flatMap,都是进行变换,返回Observable对象,激活并发送事件
和flatmap区别
- compose是唯一一个能从数据流中得到原始Observable的操作符,需要对整个数据流产生作用的操作需使用compose来实现。如subscribeOn()和observeOn(),在flatMap中使用的话,仅对在flatMap中创建的Observable起作用,不会对剩下的流产生影响.
- compose是对Observable整体的变换。flatMap转换Observable里的每一个事件,compose转换的是整个Observable数据流。
- flatMap每发送一个事件都创建一个Observable,效率低。compose只在主干数据流上执行操作。
- 建议使用compose代替flatMap。
first操作符
只发送符合条件的第一个事件。如:可以结合contact做网络三级缓存
first操作符代码示例
1 | // 从缓存获取 |
timer操作符
定时器,可以做定时操作或延迟操作
timer操作符代码示例
1 | Observable.timer(2, TimeUnit.SECONDS) |
interval操作符
定时的周期性操作,与timer操作符的区别是可以重复操作
throttleFirst操作符
类似debounce操作符,时间间隔太短就会丢弃事件。可用于防抖操作,如防止双击
throttleFirst操作符代码示例
1 | RxView.clicks(button) |
Single操作符
相当于Observable的精简版。观察者回调的不是onNext/onError/onCompleted,而是回调onSuccess/onError
subject操作符
既是事件的生产者,又是事件的消费者
subject操作符代码示例
1 | Subject subject = PublishSubject.create(); |
参考资料->RxJava详解-由浅入深
这是当时的文章名称,如今去看作者已经进行了更新RxJava 从入门到出轨,也是骚的不行~