- 1.简介
- 1)RxJava它就是一个实现异步操作的库:a library for composing asynchronous and event-based programs using observable sequences for the Java VM
- 2)Android 创造的 AsyncTask 和Handler ,其实都是为了让异步代码更加简洁,与众不同之处在于,随着程序逻辑变得越来越复杂,它依然能够保持简洁,这里的简洁是逻辑上的简洁而不是代码量的减少。
- 3)优点:流式接口,典型的构建者模式,是一条从上到下的链式调用,没有任何嵌套,需求越是复杂越是明显
Demo:界面上有一个自定义的视图 imageCollectorView ,它的作用是显示多张图片,并能使用 addImage(Bitmap) 方法来任意增加显示的图片。现在需要程序将一个给出的目录数组 File[] folders 中每个目录下的 png 图片都加载出来并显示在 imageCollectorView 中。需要注意的是,由于读取图片的这一过程较为耗时,需要放在后台执行,而图片的显示则必须在 UI 线程执行。常用的实现方式有多种,我这里贴出其中一种:
自动 Lambda 化的预览会让你更加清晰地看到程序主逻辑,但不建议学习 Retrolambda
- 2.设计原理——扩展的观察者模式
- 1)控件需要先setOnClickListener注册register/订阅Subscribe,订阅之后用户点击按钮的瞬间,Android Framework 就会将点击事件发送给已经注册的 OnClickListener 。采取这样被动的观察方式,既省去了反复检索状态的资源消耗,也能够得到最高的反馈速度。观察者观察数据源的变化,当然是先订阅报纸,当报纸中心有新报纸出现时,会把这个变化的消息通知给注册订阅付款者,和现实有点不同的是,可观察者数据源是主动推送事件给观察者,这里的观察者还不是现实生活中主动观察,它其实只需要仅仅先登个记,登个记后就不需要担心数据变化来不了通知,后续也无需它操心,总之就是万事大吉了,把耦合已经降低到了最低。
- 2)其扩展性在于其数据源可观察者下发给观察者/订报者/注册用户 事件流的类型更细化了。
- 1)控件需要先setOnClickListener注册register/订阅Subscribe,订阅之后用户点击按钮的瞬间,Android Framework 就会将点击事件发送给已经注册的 OnClickListener 。采取这样被动的观察方式,既省去了反复检索状态的资源消耗,也能够得到最高的反馈速度。观察者观察数据源的变化,当然是先订阅报纸,当报纸中心有新报纸出现时,会把这个变化的消息通知给注册订阅付款者,和现实有点不同的是,可观察者数据源是主动推送事件给观察者,这里的观察者还不是现实生活中主动观察,它其实只需要仅仅先登个记,登个记后就不需要担心数据变化来不了通知,后续也无需它操心,总之就是万事大吉了,把耦合已经降低到了最低。
3.具体实现
- 1)需要客户端/观察者实现具体的事件被派下来的业务逻辑。Observer 接口的实现的两种方式。
方式一:
方式二:内置了一个实现了 Observer 的抽象类:Subscriber。 Subscriber 对 Observer 接口进行了一些扩展
两种方式的区别: 1.1)onStart(): 这是 Subscriber 增加的方法。它会在 subscribe 刚开始,而事件还未发送之前被调用,可以用于做一些准备工作,例如数据的清零或重置。这是一个可选方法,默认情况下它的实现为空。需要注意的是,如果对准备工作的线程有要求(例如弹出一个显示进度的对话框,这必须在主线程执行), onStart() 就不适用了,因为它总是在 subscribe 所发生的线程被调用,而不能指定线程。要在指定的线程来做准备工作,可以使用 doOnSubscribe() 方法,具体可以在后面的文中看到。
2.1)unsubscribe(): 这是 Subscriber 所实现的另一个接口 Subscription 的方法,用于取消订阅。在这个方法被调用后,Subscriber 将不再接收事件。一般在这个方法调用前,可以使用 isUnsubscribed() 先判断一下状态。 unsubscribe() 这个方法很重要,因为在 subscribe() 之后, Observable 会持有 Subscriber 的引用,这个引用如果不能及时被释放,将有内存泄露的风险。所以最好保持一个原则:要在不再使用的时候尽快在合适的地方(例如 onPause() onStop() 等方法中)调用 unsubscribe() 来解除引用关系,以避免内存泄露的发生。
- 1)需要客户端/观察者实现具体的事件被派下来的业务逻辑。Observer 接口的实现的两种方式。
2)创建数据源被观察者Observable,它决定什么时候触发事件以及触发怎样的事件。 RxJava 使用 create() 方法来创建一个 Observable ,并为它定义事件触发规则,OnSubscribe 对象作为参数,会被存储在返回的 Observable 对象中,它的作用相当于一个计划表,并接管了framworks的行为,它会主动调用注册者的回调方法,当 Observable 被订阅的时候,OnSubscribe 的 call() 方法会自动被调用,事件序列就会依照设定的顺序依次触发:
方式一:
注意:网络请求的结果在请求返回之前是未知的,内容待定,所有事件在一瞬间被全部发送出去,而不是夹杂一些确定或不确定的时间间隔或者经过某种触发器来触发的。
方式二:创造事件序列的方法just(T…): 将传入的参数依次发送出来。
方式三:建立关联,即杂志订阅了读者,虽然API设计有点不符合思维逻辑,但是更符合流式API的设计规范。
1) 调用 Subscriber.onStart() 。这个方法在前面已经介绍过,是一个可选的准备方法。
2) 调用 Observable 中的 OnSubscribe.call(Subscriber) 。在这里,事件发送的逻辑开始运行。从这也可以看出,在 RxJava 中, Observable 并不是在创建的时候就立即开始发送事件,而是在它被订阅的时候,即当 subscribe() 方法执行的时候。
3) 将传入的 Subscriber 作为 Subscription 返回。这是为了方便 unsubscribe().其实还是由onSubscribe来call的
方式四:个性化定制,支持不完整定义的回调
注意: Action0 是 RxJava 的一个接口,它只有一个方法 call(),这个方法是无参无返回值的;由于 onCompleted() 方法也是无参无返回值的,因此 Action0 可以被当成一个包装对象,将 onCompleted() 的内容打包起来将自己作为一个参数传入 subscribe() 以实现不完整定义的回调。这样其实也可以看做将 onCompleted() 方法作为参数传进了 subscribe(),相当于其他某些语言中的『闭包』。 Action1 也是一个接口,它同样只有一个方法 call(T param),这个方法也无返回值,但有一个参数;与 Action0 同理,由于 onNext(T obj) 和 onError(Throwable error) 也是单参数无返回值的,因此 Action1 可以将 onNext(obj) 和 onError(error) 打包起来传入 subscribe() 以实现不完整定义的回调。事实上,虽然 Action0 和 Action1 在 API 中使用最广泛,但 RxJava 是提供了多个 ActionX 形式的接口 (例如 Action2, Action3) 的,它们可以被用以包装不同的无返回值的方法。
http://gank.io/post/560e15be2dca930e00da1083
https://www.zhihu.com/question/35511144
http://blog.csdn.net/lzyzsd
https://github.com/lzyzsd/Awesome-RxJava
http://coderrobin.com/2015/07/17/RxAndroid初探/
https://www.zhihu.com/question/32179258
http://www.cnblogs.com/tiantianbyconan/p/4578699.html
http://blog.csdn.net/caroline_wendy/article/details/50444461
https://www.zhihu.com/question/32209660
https://www.zhihu.com/question/32177130
https://github.com/ReactiveX/RxJava
https://github.com/ReactiveX/RxAndroid