初识RxJava
来源:互联网 发布:视频音乐提取软件 编辑:程序博客网 时间:2024/06/07 20:37
为什么要用RxJava
因为项目里用到了RxJava,所以最近开始接触它,接触第一天简直是一脸懵逼啊,但是在看了二十几遍“大头鬼Bruce”和“仍物线”的对于RxJava的讲解后,发现RxJava真是太棒了!它其中的链式编程颠覆了我们之前的命令式编程的思想,其最大的好处就是简洁,程序在不断变复杂的情况下,它依然可以保持简洁和很高的可读性。
RxJava是什么
RxJava 的本质可以压缩为异步这一个词。说到根上,它就是一个实现异步操作的库,而别的定语都是基于这之上的。
RxJava的几个基本概念:
- Observable:被观察者
- Observer:观察者
- subscribe:订阅
Observable 和 Observer 通过 subscribe() 方法实现订阅关系,对于初学者来说,刚开始的时候可能和我一样,对于订阅这个词的理解不太到位,慢慢的我觉得它更像是一种关系,类似于绑定、注册等,比如A和B之间通过订阅产生了一种关系。
Hello World
其实,对于初学者来说,写一个RxJava的Hellp World并不难,只需要三步就可以搞定:
- 一、创建Observable
- 二、创建Observer
- 三、将Observable 和 Observer 通过 subscribe() 方法实现订阅关系
下面我们一起来写一下
- 创建Observable,创建一个Observable对象很简单,直接调用Observable.create即可
Observable<String> myObservable = Observable.create( new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> sub) { sub.onNext("Hello, world!"); sub.onCompleted(); } } );
2.这里定义的Observable对象仅仅发出一个Hello World字符串,然后就结束了。接着我们创建一个Subscriber来处理Observable对象发出的字符串。
Observer<String> observer = new Observer<String>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(String s) { textView.setText(s); } });
3.将Observable 和 Observer 通过 subscribe() 方法实现订阅关系:
myObservable.subscribe(observer);
OK,大功告成,此时我们就可以输出Hello, world!了。
简化代码
其实上面的代码我们可以简化为一行:
Observable<String> myObservable = Observable.just("Hello, world!");
简单吧!
Subscriber
除了 Observer 接口之外,RxJava 还内置了一个实现了 Observer 的抽象类:Subscriber。 Subscriber 对 Observer 接口进行了一些扩展,但他们的基本使用方式是完全一样的:
Subscriber<String> mySubscriber = new Subscriber<String>() { @Override public void onNext(String s) { System.out.println(s); } @Override public void onCompleted() { } @Override public void onError(Throwable e) { } };
它们的区别对于使用者来说主要有两点:
onStart(): 这是 Subscriber 增加的方法。它会在 subscribe 刚开始,而事件还未发送之前被调用,可以用于做一些准备工作,例如数据的清零或重置。这是一个可选方法,默认情况下它的实现为空。需要注意的是,如果对准备工作的线程有要求(例如弹出一个显示进度的对话框,这必须在主线程执行), onStart() 就不适用了,因为它总是在 subscribe 所发生的线程被调用,而不能指定线程。要在指定的线程来做准备工作,可以使用 doOnSubscribe() 方法,具体可以在后面的文中看到。
unsubscribe(): 这是 Subscriber 所实现的另一个接口 Subscription 的方法,用于取消订阅。在这个方法被调用后,Subscriber 将不再接收事件。一般在这个方法调用前,可以使用 isUnsubscribed() 先判断一下状态。 unsubscribe() 这个方法很重要,因为在 subscribe() 之后, Observable 会持有 Subscriber 的引用,这个引用如果不能及时被释放,将有内存泄露的风险。所以最好保持一个原则:要在不再使用的时候尽快在合适的地方(例如 onPause() onStop() 等方法中)调用 unsubscribe() 来解除引用关系,以避免内存泄露的发生。
注:以上两段取自http://gank.io/post/560e15be2dca930e00da1083#toc_10
Action的引入
我们看到,上面的代码有时我们可能并不关系OnComplete和OnError,这时我们就可以用到Action1。最后的代码可以写成如下:
Observable.just("Hello, world!") .subscribe(new Action1<String>() { @Override public void call(String s) { System.out.println(s); } });
有Action1当然会有Action0,它们的区别主要在与Action1是有参数的,可以替换onNext和OnComplete;而Aciton0是无参的,可以替换OnError
线程控制
因为RxJava 的本质可以压缩为异步,所以在RxJava中,线程的切换必不可少,控制线程的方法有两种:subscribeOn和observeOn。这里我就不细讲了,贴一段用法的代码,具体的区别可以看上面链接的文章.
Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { subscriber.onNext("123"); subscriber.onCompleted(); } }).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<String>() { @Override public void call(String s) { textView.setText(str); } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { textView.setText("错误!"); } }, new Action0() { @Override public void call() { } });
初识简单操作符
RxJava之所以灵活多遍,可以适用在很多场景,操作符算是头功。操作符主要解决了对Observable对象的变换的问题,用于在Observable和最终的Subscriber之间修改Observable发出的事件。像上面用到的just,create,它们都属于操作符。常用的操作符还有map、flatmap、concat、zip等等,这里说几个简单的,具体操作符介绍大全可以看这篇文章:http://blog.chinaunix.net/uid-20771867-id-5187376.html 大神写的非常非常全。
map
首先看一段代码:
Observable.just("a") .map(new Func1<String, Integer>() { @Override public Integer call(String s) { return s.hashCode(); } }) .subscribe(new Action1<Integer>() { @Override public void call(Integer s) { System.out.print(Integer.toString(s)); } });
你猜的没错,最后的输出结果为a的hashCode码97。所以,我们可以想到,map()的作用为:
用于变换Observable对象,map操作符返回一个Observable对象,这样就可以实现链式调用,在一个Observable对象上多次使用map操作符,最终将最简洁的数据传递给Subscriber对象。
first
同样的,我们再看一段代码:
Observable.just(1,2,3,4,5,6,7,8) .first() .subscribe(new Subscriber<Integer>() { @Override public void onNext(Integer item) { System.out.println("Next: " + item); } @Override public void onError(Throwable error) { System.err.println("Error: " + error.getMessage()); } @Override public void onCompleted() { System.out.println("Sequence complete."); } });
输出结果为:
Next: 1Sequence complete.
因此,first的作用为:first操作符是把源Observable产生的结果的第一个提交给订阅者,注意:这里的第一个并不一定是数字上的第一个,而是符合输出条件的第一个,看一下下面的例子:
Observable.create(new Observable.OnSubscribe<Integer>() { @Override public void call(Subscriber<? super Integer> subscriber) { subscriber.onNext(1); subscriber.onNext(2); subscriber.onNext(3); subscriber.onCompleted(); } }).first(new Func1<Integer, Boolean>() { @Override public Boolean call(Integer integer) { return integer > 2; } }).subscribe(new Action1<Integer>() { @Override public void call(Integer integer) { System.out.print(integer); } });
这个例子最终的输出结果为3,这下明白了吧。好了,操作符合就暂时举这两个例子,更多的大家可以看上面的链接,以后我有时间的话会专门再写一篇操作符的文章。
好了,这就是我对RxJava的初步理解,有写的不好的地方请大家多多指教。最后附上一个我自己写的很简单的demo,代码很简单,但是对于初学者来说都是很经典的东西:
http://download.csdn.net/detail/dzx997681136/9654805
“大头鬼Bruce”和“仍物线”两位大神的RxJava的介绍给了我很大的帮助,附上两篇文章的链接:
http://gank.io/post/560e15be2dca930e00da1083#toc_10
http://blog.csdn.net/lzyzsd/article/details/41833541/
- RxJava 初识
- Rxjava 初识
- 初识RxJava
- 初识RxJava
- 初识RxJava
- 初识RxJava
- RxJava 初识
- 初识RxJava
- RxJava系列之一 初识Rxjava
- 初识RxJava(入门篇)
- RxJava学习一:初识
- 初识RxJava和Retrofit
- RxJava 系列之初识
- 初识RXJava+Retrofit
- RxJava学习(一),RxJava初识
- rxjava系列(一)-- 初识Rxjava
- Android——初识RxJava
- Retrofit笔记->结合Rxjava初识
- JDBC 练习
- java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
- 求两字符串的最长公共连续子串
- OD选项设置-本地变量的显示格式
- 算法之——快速排序
- 初识RxJava
- Java读取与写入图片文件
- C#控制台输入数组方法
- 集合框架一
- D5_正则表达式初步
- poj_2996 Help Me with the Game(模拟)
- HDU ACM 11 2047 阿牛的EOF牛肉串
- C/C++实现奇偶判断、质数判断、求解最大公约数、最小公倍数、最大奇约数等
- P1121 环状最大两段子段和(DP)