RxJava的使用
前言
RxJava及RxAndroid比较详细的介绍可以参考该文档《给 Android 开发者的 RxJava 详解》
基本介绍
ReactiveX 及 RxJava使用大部分来自和参考《给Android 开发者的 RxJava 详解》和《RxJava 入门》;进行整理及增加了部分自己的理解。
什么是 ReactiveX
ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。
实时数据处理是一件普通的现象,有一个高效、干净和可扩展的方式来处理这些情景是重要的。使用 Observables 和 Operators 来熟练操作它们。ReactiveX 提供一个可组合又灵活的 API 来创建和处理数据流,同时简化了异步编程带来的一些担忧,如:线程创建和并发问题。
RxJava 简介
RxJava是 ReactiveX 在 Java 上的开源的实现。RxJava可以轻松处理不同运行环境下的后台线程或UI线程任务的框架。RxJava 的异步实现,是通过一种扩展的观察者模式来实现的。
Observable(可观察者,即被观察者) 和 Subscriber(订阅者)是两个主要的类。在 RxJava 上,一个 Observable 是一个发出数据流或者事件的类,Subscriber 是一个对这些发出的 items (数据流或者事件)进行处理(采取行动)的类。
Observable
和Observer
通过 subscribe()
方法实现订阅关系。一个 Observable 的标准流发出一个或多个item,然后成功完成或者出错。一个 Observable 可以有多个 Subscribers,并且通过 Observable 发出的每一个 item,该 item 将会被发送到 Subscriber.onNext() 方法来进行处理。一旦 Observable 不再发出 items,它将会调用 Subscriber.onCompleted() 方法,或如果有一个出错的话Observable 会调用 Subscriber.onError() 方法。
onNext(): RxJava的事件回调方法,针对普通事件。
onCompleted(): 事件队列完结。RxJava 不仅把每个事件单独处理,还会把它们看做一个队列。RxJava 规定,当不会再有新的 onNext() 发出时,需要触发 onCompleted() 方法作为标志。
onError(): 事件队列异常。在事件处理过程中出异常时,onError() 会被触发,同时队列自动终止,不允许再有事件发出。
在一个正确运行的事件序列中,onCompleted() 和 onError() 有且只有一个,并且是事件序列中的最后一个。需要注意的是,onCompleted() 和 onError() 二者也是互斥的,即在队列中调用了其中一个,就不应该再调用另一个。
图1-RxJava 的观察者模式(来自《给 Android 开发者的 RxJava 详解》)
RxAndroid是RxJava针对android平台增加的移植版本;使用RxAndroid也需要引入RxJava包。
GitHub地址及AS引入依赖
GitHub
链接:
https://github.com/ReactiveX/RxJava
https://github.com/ReactiveX/RxAndroid
引入依赖:
compile'io.reactivex:rxandroid:1.1.0'
compile'io.reactivex:rxjava:1.1.0'
基本使用
1. 创建Subscriber(Observer)
Subscriber是Observer接口的一个抽象实现;推荐使用Subscriber,实际上RxJava在subscibe过程中,会先将Observer转换为一个Subscriber。
final Subscriber<String> tempSubsciber = new Subscriber<String>() { @Override public void onCompleted() { Log.d(TAG, "onCompleted()"); } @Override public void onError(Throwable e) { Log.d(TAG, "onError() e=" + e); } @Override public void onNext(String s) { Log.d(TAG, "onNext() data=" + s); } } |
2. 创建Observable
Observable<String> tempObservable = Observable.create( new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { subscriber.onNext("01"); subscriber.onNext("02"); subscriber.onNext("03"); } }); |
3. subscribe (订阅)
tempObservable.subscribe(tempSubsciber); |
subscribe()主要做了一下工作:
1) 调用subscriber.onStart()。
2) 调用 Observable 中的 OnSubscribe.call(Subscriber) 。处理事件发送的逻辑,在 RxJava 中, Observable并不是在创建的时候就立即开始发送事件,而是在它被订阅的时候,即当 subscribe() 方法执行的时候。
3) 将传入的 Subscriber 作为 Subscription 返回。这是为了方便 unsubscribe()。
4. 其他简洁使用方式
1) 快捷创建Observable
just(T...):将传入的参数依次发送出来。
final Observable observable = Observable.just("info1", "info2", "info3"); |
from(T[])/ from(Iterable<? extends T>) : 将传入的数组或 Iterable 拆分成具体对象后,依次发送出来。
final String[] infos = {"info1", "info2", "info3"}; final Observable observable = Observable.from(infos); |
2) Subscribe不完整定义的回调
final Action0 onCompletedAction = new Action0() { @Override public void call() { //相当于Subscriber的onCompleted() } }; final Action1<String> onNextAction = new Action1<String>() { @Override public void call(String s) { //相当于Subscriber的onNext(Sring s) } }; final Action1<Throwable> onErrorAction = new Action1<Throwable>() { @Override public void call(Throwable throwable) { //相当于Subscriber的onError(Throwable e) } }; observable.subscribe(onNextAction); // 自动创建 Subscriber ,并使用 onNextAction 和 onErrorAction 来定义 onNext() 和 onError() observable.subscribe(onNextAction, onErrorAction); // 自动创建 Subscriber ,并使用 onNextAction、 onErrorAction 和 onCompletedAction 来定义 onNext()、 onError() 和 onCompleted() observable.subscribe(onNextAction, onErrorAction, onCompletedAction); |
到此,已可以最简单方式使用RxJava。
5. 取消订阅-Unsubscribe()
Observable.subscribe()的返回值是一个 Subscription 对象。Subscription 类只有两个方法,unsubscribe() 和 isUnsubscribed()。
unsubscribe() 这个方法很重要,因为在subscribe() 之后, Observable 会持有 Subscriber 的引用,这个引用如果不能及时被释放,将有内存泄露的风险。
为了防止可能的内存泄露,要在不再使用的时候尽快在合适的地方(例如 onPause() onStop() onDestroy等方法中),用Subscription.isUnsubscribed() 检查你的 Subscription 是否是 unsubscribed,若没有,可以通过Subscription.unsubscribe()取消订阅,Subscriber 将不再接收事件。
如果调用了Subscription.unsubscribe() ,Unsubscribing将会对 items 停止通知给你的 Subscriber,并允许垃圾回收机制释放对象,防止任何 RxJava 造成内存泄露。
如果你正在处理多个 Observables 和 Subscribers,所有的 Subscription 对象可以添加到 CompositeSubscription,然后可以使用 CompositeSubscription.unsubscribe() 方法在同一时间进行退订(unsubscribed)。
RxJava的使用的更多相关文章
- Android性能优化之利用Rxlifecycle解决RxJava内存泄漏
前言: 其实RxJava引起的内存泄漏是我无意中发现了,本来是想了解Retrofit与RxJava相结合中是如何通过适配器模式解决的,结果却发现了RxJava是会引起内存泄漏的,所有想着查找一下资料学 ...
- Android消息传递之基于RxJava实现一个EventBus - RxBus
前言: 上篇文章学习了Android事件总线管理开源框架EventBus,EventBus的出现大大降低了开发成本以及开发难度,今天我们就利用目前大红大紫的RxJava来实现一下类似EventBus事 ...
- 【知识必备】RxJava+Retrofit二次封装最佳结合体验,打造懒人封装框架~
一.写在前面 相信各位看官对retrofit和rxjava已经耳熟能详了,最近一直在学习retrofit+rxjava的各种封装姿势,也结合自己的理解,一步一步的做起来. 骚年,如果你还没有掌握ret ...
- Android MVP+Retrofit+RxJava实践小结
关于MVP.Retrofit.RxJava,之前已经分别做了分享,如果您还没有阅读过,可以猛戳: 1.Android MVP 实例 2.Android Retrofit 2.0使用 3.RxJava ...
- 【腾讯Bugly干货分享】基于RxJava的一种MVP实现
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57bfef673c1174283d60bac0 Dev Club 是一个交流移动 ...
- Rxjava Subjects
上次提到调用observable的publish和connect方法后可以将一个Observable发出的对象实时传递到订阅在上的subscriber. 这个和Rxjava中Subject的概念十分相 ...
- Rxjava cold/hot Observable
create Observable分为cold以及hot两种,cold主要是静态的,每次subscribe都是从头开始互不干扰,而hot的在同一时刻获得的值是一致的 cold Observable 使 ...
- Android开发学习之路-Android中使用RxJava
RxJava的核心内容很简单,就是进行异步操作.类似于Handler和AsyncTask的功能,但是在代码结构上不同. RxJava使用了观察者模式和建造者模式中的链式调用(类似于C#的LINQ). ...
- [Android]在Dagger 2中使用RxJava来进行异步注入(翻译)
以下内容为原创,欢迎转载,转载请注明 来自天天博客: # 在Dagger 2中使用RxJava来进行异步注入 > 原文: 几星期前我写了一篇关于在Dagger 2中使用*Producers*进行 ...
- RXJava by Example--转
原文地址:https://www.infoq.com/articles/rxjava-by-example Key takeaways Reactive programming is a specif ...
随机推荐
- C++中的namespace用法
关键字namespace定义了一个名字空间,里面的变量和函数,声明在此名字空间外使用须在前面加名字空间名称.例如: #include<iostream.h>namespace my{ in ...
- linux中应用程序main函数中没有开辟进程的,它应该在那个进程中运行呢?
1.main函数是一个进程还是一个线程? 不知道你是用c创建的,还是用java创建的. 因为它们都是以main()做为入口开始运行的. 是一个线程,同时还是一个进程. 在现在的操作系统中,都是多线程的 ...
- VPN column: PPTP(2)--PPTP协议解析
zhu_hit原创,如需转载请注明出处.Thanks. PPTP协议大体上可以分为两部分:控制层连接和隧道,下面简要介绍两部分的功能.如果要详细了解PPTP协议请阅读RFC文档. 一. Control ...
- git commit 之后 push 之前,想删除 个别的commit 文件
git rm --cached <file_name> git commit "删除了<file_name>文件" git rm --cached < ...
- mappingResources,annotatedClasses(映射)
这两个是有本质区别的,光看名字也能看出来,哈哈,好了,入正题: mappingResources用于指定少量的hibernate配置文件像这样 Xml代码 1 2 3 4 5 6 7 <prop ...
- bzoj1934 bzoj2768
最小割的经典模型,体现出最小割的基本定义,把两个集合划分的最小代价 把一开始同意的人连源点,不同意的连汇点,有关系的人之间连边,流量都为1 不难发现,割两点(人)间的边就相当于朋友之间发生冲突 割到连 ...
- DataView.RowFilter筛选DataTable中的数据
//定义一个DataView ,得到一个全部职员的视图DataView dataView1 = DbHelperSQL.QueryDataView(sql); //过滤得到一个只显示男职员的视图 da ...
- UVA 1324 The Largest Clique 最大团(强连通分量,变形)
题意:给一个有向图,要求找出一些点,使得这些点中的任意点对,要么可以互通,要么单向可达. 思路:最低只要求单向可达即可,即a->b都可以算进去. 强连通分量内的点肯定是满足要求的,可以全选,但是 ...
- easyui资源
官网地址:http://www.jeasyui.com/index.php(相关文档示例,有demo, tutorial, documentation) 未混淆的源码:http://jquery-ea ...
- Java [leetcode 27]Remove Element
题目描述: Given an array and a value, remove all instances of that value in place and return the new len ...