RxJava2笔记(1)—Hello RxJava
来源:互联网 发布:淘宝直播文案怎么写 编辑:程序博客网 时间:2024/06/02 04:49
0.前言:
本文讨论是基于是rxJava2.+版本。
先来段helloRxJava,然后再阐述下各种概念。
库的引入:
compile ‘io.reactivex.rxjava2:rxjava:x.y.z’
具体版本号请参考github上最新的代码:Github
这个框架是一个线程可控的事件收发框架。并且提供了许多的操作符来适应各种场景来做这件事。它是采用的观察者模式。
1.Hello RxJava
1.1:Observer观察者,事件接收者。
Observer即观察者,根据观察者模式的思想,它是事件的接受方,所以它决定当收到事件的时候将有怎样的行为(数据处理)。
Observer<String> observer = new Observer<String>() { @Override public void onSubscribe(Disposable d) { Log.d(TAG, "subscribe"); } @Override public void onNext(Integer value) { Log.d(TAG, "" + value); } @Override public void onError(Throwable e) { Log.d(TAG, "error"); } @Override public void onComplete() { Log.d(TAG, "complete"); }};
1.2:Observable被观察者,事件发送者。
Observable即被观察者,根据观察者模式的思想,他既然是被观察的一方,那么它就决定了传达给观察者们的事件的时机和内容。
Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { emitter.onNext(1); emitter.onNext(2); emitter.onNext(3); emitter.onComplete(); } });
注意这里的Observable创建的方式.create()。
1.3:双方建立连接
observable.subscribe(observer);
只有简历连接之后,事件的收发端才开始工作。
建立连接之后的运行结果:
11-29 17:07:54.491 29573-29573/zj.playrxjava D/PlayRxJava: subscribe11-29 17:07:54.491 29573-29573/zj.playrxjava D/PlayRxJava: 111-29 17:07:54.491 29573-29573/zj.playrxjava D/PlayRxJava: 211-29 17:07:54.491 29573-29573/zj.playrxjava D/PlayRxJava: 311-29 17:07:54.491 29573-29573/zj.playrxjava D/PlayRxJava: complete
1.4:合并代码,链式调用:
Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { emitter.onNext(1); emitter.onNext(2); emitter.onNext(3); emitter.onComplete(); } }).subscribe(new Observer<Integer>() { @Override public void onSubscribe(Disposable d) { Log.d(TAG, "subscribe"); } @Override public void onNext(Integer value) { Log.d(TAG, "" + value); } @Override public void onError(Throwable e) { Log.d(TAG, "error"); } @Override public void onComplete() { Log.d(TAG, "complete"); } });
3.事件模型
它的事件模型是一个队列结构,F1FO,先进先出。
也就是说,事件发送者Observerble先后发送三个事件A、B、C,那么事件接收者Observer收到的事件顺序同样为A、B、C。
基于此,RxJava提供了不同类型的事件流控制单元。这体现在代码里就是不同的方法,具备不同的属性,这些属性的不同会导致事件传输的结果不同。并且,同时作用于事件收发俩端。
它体现在事件发送端(Observable)时则是主动调的方法,它体现在事件接收端(Observer)时则是回调函数,类似如下代码:
Observable 发送端: Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { emitter.onNext(1); } })Observer 接收端: subscribe(new Observer<Integer>() { ...... @Override public void onNext(Integer value) { Log.d(TAG, "" + value); } ...... }
那么下面来描述下这几个控制单元。
3.1.onNext
这个控制单元平淡无奇,就是事件发送端调一次(emitter.onNext(1)),事件接收端接收回调(onNext)一次,属于最基本的”事件发送”方法。
3.2.onComplete
当事件发送端发送了一个onComplete后, 事件发送端onComplete之后的事件将会继续发送, 而事件接收端收到onComplete事件之后将不再继续接收事件。
3.3.onError
这个跟上一个onComplete有点像。
我们来把上面的代码改成这样:
@Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { Log.e(TAG,"emitter.onNext(1)"); emitter.onNext(2); Log.e(TAG,"emitter.onNext(2)"); emitter.onError(null); Log.e(TAG,"emitter.onError(null)"); emitter.onNext(3); Log.e(TAG,"emitter.onNext(3)"); emitter.onComplete(); Log.e(TAG,"eemitter.onComplete()"); }
接收端打出如下日志:
11-29 20:06:33.090 25658-25658/zj.playrxjava D/PlayRxJava: subscribe11-29 20:06:33.091 25658-25658/zj.playrxjava D/PlayRxJava: 111-29 20:06:33.091 25658-25658/zj.playrxjava D/PlayRxJava: 211-29 20:06:33.093 25658-25658/zj.playrxjava D/PlayRxJava: error
发送端打出如下日志:
11-29 20:08:44.570 31771-31771/zj.playrxjava E/PlayRxJava: emitter.onNext(1)11-29 20:08:44.570 31771-31771/zj.playrxjava E/PlayRxJava: emitter.onNext(2)11-29 20:08:44.570 31771-31771/zj.playrxjava E/PlayRxJava: emitter.onError(null)11-29 20:08:44.571 31771-31771/zj.playrxjava E/PlayRxJava: emitter.onNext(3)11-29 20:08:44.571 31771-31771/zj.playrxjava E/PlayRxJava: eemitter.onComplete()
目前为止这个方法和onComplete是一样的,但是如果我们把代码改成这样程序就会崩溃,也就是说,onError事件是不能发送俩次的。
@Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { Log.e(TAG,"emitter.onNext(1)"); emitter.onNext(2); Log.e(TAG,"emitter.onNext(2)"); emitter.onError(null); Log.e(TAG,"emitter.onError(null)"); emitter.onError(null); Log.e(TAG,"emitter.onError(null)"); emitter.onNext(3); Log.e(TAG,"emitter.onNext(3)"); emitter.onComplete(); Log.e(TAG,"eemitter.onComplete()"); }
抛出如下异常:
11-29 20:11:07.014 6665-6665/zj.playrxjava E/AndroidRuntime: FATAL EXCEPTION: main Process: zj.playrxjava, PID: 6665 java.lang.NullPointerException: onError called with null. Null values are generally not allowed in 2.x operators and sources. at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onError(ObservableCreate.java:74) at zj.playrxjava.MainActivity$5.subscribe(MainActivity.java:134) at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40) at io.reactivex.Observable.subscribe(Observable.java:10179) at zj.playrxjava.MainActivity.baseUse(MainActivity.java:142) at zj.playrxjava.MainActivity.onCreate(MainActivity.java:41) at android.app.Activity.performCreate(Activity.java:6736) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2641) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2749) at android.app.ActivityThread.-wrap12(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1498) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:160) at android.app.ActivityThread.main(ActivityThread.java:6197) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:874) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:764)
3.4.onSubscribe
这个方法比较特别相较于上面说那几个比较特别。
他是在订阅的时候(observable.subscribe(observer)),也就是observable调用subscribe的时候,observer这个方法进行回调,并且,注意这个并且比较重要,在observer回调方法public void onSubscribe(Disposable d)内的回调参数内有一个Disposable d,这就引入了下一个概念Disposable。
另外需要注意的是subscribe的多个重载方法:
【这里我转的一段Season_zlc大神的描述】
作者:Season_zlc
链接:http://www.jianshu.com/p/464fa025229e
public final Disposable subscribe() {} public final Disposable subscribe(Consumer<? super T> onNext) {} public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError) {} public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete) {} public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete, Consumer<? super Disposable> onSubscribe) {} public final void subscribe(Observer<? super T> observer) {}
我们之前调用就是最后一个
public final void subscribe(Observer observer) {}。
这里着重说下其他几个:
- 不带任何参数的subscribe() 表示下游不关心任何事件,你上游尽管发你的数据去吧, 老子可不管你发什么.
- 带有一个Consumer参数的方法表示下游只关心onNext事件, 其他的事件我假装没看见, 因此我们如果只需要onNext事件可以这么写:
Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { Log.d(TAG, "emit 1"); emitter.onNext(1); Log.d(TAG, "emit 2"); emitter.onNext(2); Log.d(TAG, "emit 3"); emitter.onNext(3); Log.d(TAG, "emit complete"); emitter.onComplete(); Log.d(TAG, "emit 4"); emitter.onNext(4); } }).subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.d(TAG, "onNext: " + integer); } });
- 其他几个方法同理, 这里就不一一解释了.
3.5.Disposable
这个Disposable对象是啥呢?
我们看他的代码就俩方法,dispose,isDisposed:
/** * Represents a disposable resource. */public interface Disposable { /** * Dispose the resource, the operation should be idempotent. */ void dispose(); /** * Returns true if this resource has been disposed. * @return true if this resource has been disposed */ boolean isDisposed();}
这里我主要关注他的dispose()方法,这个方法也比较特殊,为什么说它特殊呢,它的作用是接收端单方面地切断事件接收流,所以它一般是在observer内进行调用,我们知道事件的发起都是在Observable内的,也就是说维持事件流动向一般都是发生在事件发送端,然而,正因为有它的存在,在事件接收端也具备了影响事件流传递的功能,但是,这只是事件接收端单方面的操作,也就是说,即便是在接收端停止了事件接收,在发送端却依然会按计划进行事件的发送,这也就类似于变向的收到了一个onComplete事件。
举个例子,如果我们将上面的代码修改了,在onSubscribe方法内进行一条d.dispose(),修改后的代码如下:
Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { emitter.onNext(1); emitter.onNext(2); emitter.onNext(3); emitter.onComplete(); } }).subscribe(new Observer<Integer>() { @Override public void onSubscribe(Disposable d) { Log.d(TAG, "subscribe"); d.dispose(); } @Override public void onNext(Integer value) { Log.d(TAG, "" + value); } @Override public void onError(Throwable e) { Log.d(TAG, "error"); } @Override public void onComplete() { Log.d(TAG, "complete"); } });
那么我们来看它的运行结果,肯定是除了onSubscribe()一条信息都接收不到的,我们看运行结果:
11-29 19:56:11.106 9792-9792/zj.playrxjava D/PlayRxJava: subscribe
通过结果可以看出,我们的推测没错。
本文代码:
点击下载本文demo
博客推荐:
Season_zlc的专题:RxJava2.x
给 Android 开发者的 RxJava 详解//(1.x版本)
- RxJava2笔记(1)—Hello RxJava
- RxJava2笔记(3)—RxJava结合Retrofit使用
- RxJava 1 到RxJava2
- 从零开始的RxJava之旅(3)---- RxJava进阶RxJava2
- RxJava2对比RxJava
- RxJava及RxJava2简述
- rxjava2源码笔记(二)
- RxJava学习(三)Rxjava2.0 中几种观察者模式
- 从零开始的RxJava之旅(4)---- RxJava2总结
- RXJava学习笔记(1)
- Hello Rxjava
- RxJava2笔记(2)—线程切换基础
- RxJava2笔记(4)—操作符.map()
- Rxjava2 笔记
- GreenDao笔记(1)—Hello GreenDao
- ZXing笔记(1)—Hello ZXing
- RxJava2.0学习笔记(Backpressure,Flowable)
- RxJava2.0笔记记录(一)
- 获取公众号二维码中的场景值scene_str,scene_id,php开发公众平台场景值
- Hive_应用设计
- Android开发中实用的脚本工具
- HTML5 WebGL 的 3D 仓储管理系统
- DataBinding结合RecyclerView动态加载网络数据
- RxJava2笔记(1)—Hello RxJava
- JAVA_学生管理系统(纯java语言)
- 微信公众号的代码块插入,及一键排版
- Objective-C 中的NSValue的详解
- DCT变换、DCT反变换、分块DCT变换
- java中的静态变量、静态方法与静态代码块区别
- Oulipo
- mysql查看数据库性能常用命令
- CAD2010x64 无法找到所需的动态链接库或其他文件