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版本)