RxJava2笔记(1)—Hello RxJava

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: subscribe
11-29 17:07:54.491 29573-29573/zj.playrxjava D/PlayRxJava: 1
11-29 17:07:54.491 29573-29573/zj.playrxjava D/PlayRxJava: 2
11-29 17:07:54.491 29573-29573/zj.playrxjava D/PlayRxJava: 3
11-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: subscribe
11-29 20:06:33.091 25658-25658/zj.playrxjava D/PlayRxJava: 1
11-29 20:06:33.091 25658-25658/zj.playrxjava D/PlayRxJava: 2
11-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版本)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值