RxJava介绍
RxJava是一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库。
使用时,在gradle中引入依赖
RxJava特点
RxJava是一个异步库,那么为什么不用现成的AsyncTask/Handle/Thread这些?
1、简洁,RxJava是一条从上到下的链式调用,当需求逻辑变得更复杂时,RxJava依然可以保持简洁
2、轻量,无依赖库,jar包小于1M
3、支持多语言,兼容所有JVM语言,如Java、Clojure、Groovy、Scala等
4、多线程支持,封装了各种并发实现,如threads, pools, event loops, fibers, actors
5、基于有条件的异步执行
6、更好的避免回调地狱,Observables 能够组合而不是嵌套,从而避免开发者陷入回调地狱
RxJava使用
RxJava观察者模式4种角色
RxJava用到了设计模式中的观察者模式。
生产:
1、Observable(被观察者)
2、Subject
消费:
3、Observer(观察者)
Observer是一个接口,提供了3个方法:onNext(T t), onError(Throwable e), onCompleted()。
4、Subscriber(订阅者)
Subscriber是Observer的子类,class Subscriber
Subscriber在Observer的基础上增加了
onStart():这个方法在观察者和被观察者建立订阅关系后,而被观察者向观察者发送消息前调用,主要用于做一些初始化工作,如数据的清零或重置。
unsubscribe():这个方法用于取消订阅,若isUnsubscribed()为true,则观察者不能收到被观察者的消息。
创建Observable(被观察者)的方式
1、create,当Observable与Observer/Subscriber建立订阅关系(.subscribe(new Observer
Observable.create(Observable.OnSubscribe)
如下,观察者Subscriber 将会被调用一次 onNext() 和一次 onCompleted()
2、just,这个方法可以传1-N个类型相同的参数,并会按照传入的参数的顺序来发射它们。just()方法也可以接受列表或数组,就像from()方法,但是它不会迭代列表发射每个值,它将会发射整个列表。
Observable.just(T…)
3、from,这个方法可以传数组或Iterable
Observable.from(T[]), Observable.from(Iterable<? extends T>)
4、Observable.empty(),Observable.never(),和Observable.throw()
当我们需要一个Observable毫无理由的不再发射数据正常结束时,我们可以使用empty()。我们可以使用never()创建一个不发射数据并且也永远不会结束的Observable。我们也可以使用throw()创建一个不发射数据并且以错误结束的Observable。
创建Observer(观察者)及Subscriber(订阅者)的方式
根据Observable协议的定义,onNext可能会被调用零次或者很多次,最后会有一次onCompleted或onError调用(不会同时),传递数据给onNext通常被称作发射,onCompleted和onError被称作通知。
实现Observer接口
或实现Observer抽象类Subscriber
Subscribe(订阅)的方式
创建了 Observable 和 Observer/Subscriber 之后,再用 subscribe() 方法将它们联结起来,整条链子就可以工作了(目前在同一线程中)
场景示例
如何使用RxJava替代AsyncTask/Handle/Thread,实现“后台处理,前台回调”的异步机制?
1、简单的一次性消费
RxJava实现
2、后台处理,前台回调
RxJava实现
3、带进度条的更新
AsyncTask的实现
RxJava的实现,需要用到Subject,Subject有四个实现类,分别为AsyncSubject、BehaviorSubject、PublishSubject和ReplaySubject,每个实现类都有特定的功能,参见
因此处在AsyncTask中更改,回调暂时保留,其实这里回调可去掉
RxJava的二次封装
其实上面场景中会产生些重复代码,因此对RxJava二次封装,参见
1、线程(Scheduler)封装
每次调用,可封装为一个线程调度类
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
|
|
2、对服务器返回结果封装
3、对观察者封装
封装后的代码可简化为,以zip(合并)举例,此代码可直接放在Activity或controller中,所见及所得,一条链下来思路比较清晰。