# RxJava 2.x入门新姿势一

### 引言

经过几年的发展，响应式编程已经是很流行了，在Android开发中的应用也非常的广泛，身为Android开发者，则是必须掌握的技术。

### 正文

网上已经有很多很多RxJava相关的文章，视频等等教程，但是说实话对于入门，或者新手来说，确实不好理解，上来就是各种，观察者、被观察者、订阅、发布等等概念，一遍看下来直接就晕了，就感觉RxJava很难，难理解，用的时候也只是依葫芦画瓢，晕乎乎的用着，然后就没有然后了。

这里我都不说那些概念，因为讲概念太抽象，难记住，更难理解。我们用另外一个视角来学习。因为RxJava 1.x的版本 官方已经停止更新了维护了，没有学习过也没有关系，RxJava 2.x是全新的，直接学习使用就好了。

首先假设我们在工厂里上班，工厂都会有流水线，产品经过流水线生产后来订单了销售出去。 

这里假设工厂生产的是一种六边形的“Jerry帅气饼干”，上游是生产车间流水线的事件流，下游是订单产品的销售消费事件流。中间连接上下游关系的暂且叫做“Jerry帅气饼干生产消费订单管理系统”（不要脸，名字写这么长），为了下文方便抒写且用“生产订单管理系统”（PCMS）。以上图上下游对应的就是Obsersvable被观察者也是发布者，下游对应Observer观察者也是订阅者。使用RxJava代码表示上图就是：
    
    
    public void test1() {
    
            // 上游生成产品流水线
            Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
                @Override
                public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                    Log.d(TAG, "test1 ====== Observable: ------ onNext: Jerry");
                    emitter.onNext("Jerry");
                    Log.d(TAG, "test1 ====== Observable: ------ onNext: 就是");
                    emitter.onNext("就是");
                    Log.d(TAG, "test1 ====== Observable: ------ onNext: 帅");
                    emitter.onNext("帅");
                    Log.d(TAG, "test1 ====== Observable: ------ onNext: ！！！");
                    emitter.onNext("！！！");
                    Log.d(TAG, "test1 ====== Observable: ------ onComplete");
                    emitter.onComplete();
                    Log.d(TAG, "test1 ====== Observable: ------ onNext: Jerry帅炸天！！！");
                    emitter.onNext("Jerry帅炸天！！！");
                }
            });
    
            // 下游订单产品销售
            Observer<String> observer = new Observer<String>() {
                @Override
                public void onSubscribe(Disposable d) {
                    Log.d(TAG, "test1 ====== Observer: onSubscribe");
                }
    
                @Override
                public void onNext(String value) {
                    Log.d(TAG, "test1 ====== Observer: onNext: " + value);
                }
    
                @Override
                public void onError(Throwable e) {
                    Log.d(TAG, "test1 ====== Observer: onError: " + e.getMessage());
                }
    
                @Override
                public void onComplete() {
                    Log.d(TAG, "test1 ====== Observer: onComplete");
                }
            };
    
            // 连接上下游的订单管理系统
            observable.subscribe(observer);
        }
    复制代码

上述代码，上游生产车间流水线就是Observable，下游订单销售就是Observer，中间通过“生产订单管理系统”subscribe来将上下游连接起来。

运行后输出结果是： 

从输出结果来看，当上游Observable发出一个生产的饼干产品事件，下游订单销售的Observer就销售一个饼干产品事件，而且当上游调用了onComplete方法后，上游的生产事件还是生产饼干事件（继续生产了“Jerry帅炸天”饼干事件），但是下游的订单销售却没有消费掉。也就是事件产生方调用onComplete方法后，之后的事件还会继续发送，但是事件接收方就不会接收了。

我们来看看Observable的subscribe方法的参数：ObservableEmitter，Emitter顾名思义是发射器的意思，ObservableEmitter接口继承自Emitter接口：
    
    
    public interface Emitter<T> {
    
        /**
         * Signal a normal value.
         * @param value the value to signal, not null
         */
        void onNext(T value);
    
        /**
         * Signal a Throwable exception.
         * @param error the Throwable to signal, not null
         */
        void onError(Throwable error);
    
        /**
         * Signal a completion.
         */
        void onComplete();
    }
    复制代码

接口定义很简单，就三个方法，onNext我们上门已经用过了，是用来发射发送事件的，onComplete是用来表示事件发送完了，后面如果有新的事件发送，下游接收者可以不用处理，onError方法看注释说是发送一个异常事件给下游接收者。到底是不是这样，我们来试试就晓得了。
    
    
    public void test2() {
    
            // 上游生成产品流水线
            Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
                @Override
                public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                    Log.d(TAG, "test2 ====== Observable: ------ onNext: Jerry");
                    emitter.onNext("Jerry");
                    Log.d(TAG, "test2 ====== Observable: ------ onNext: 就是");
                    emitter.onNext("就是");
                    Log.d(TAG, "test2 ====== Observable: ------ onNext: 帅");
                    emitter.onNext("帅");
                    Log.d(TAG, "test2 ====== Observable: ------ onNext: ！！！");
                    emitter.onNext("！！！");
                    Log.d(TAG, "test2 ====== Observable: ------ onError");
                    emitter.onError(new IllegalStateException("Jerry饼干烤焦了，卖出去会被打！"));
                    Log.d(TAG, "test2 ====== Observable: ------ onNext: Jerry帅炸天！！！");
                    emitter.onNext("Jerry帅炸天！！！");
                }
            });
    
            // 下游订单产品销售
            Observer<String> observer = new Observer<String>() {
                @Override
                public void onSubscribe(Disposable d) {
                    Log.d(TAG, "test2 ====== Observer: onSubscribe");
                }
    
                @Override
                public void onNext(String value) {
                    Log.d(TAG, "test2 ====== Observer: onNext: " + value);
                }
    
                @Override
                public void onError(Throwable e) {
                    Log.d(TAG, "test2 ====== Observer: onError: " + e.getMessage());
                }
    
                @Override
                public void onComplete() {
                    Log.d(TAG, "test2 ====== Observer: onComplete");
                }
            };
    
            // 连接上下游的订单管理系统
            observable.subscribe(observer);
        }
    复制代码

在上游生产饼干的时候就生产了一个“Jerry饼干烤焦了，卖出去会被打！”的错误饼干事件，下游订单销售的onError出错状态会消费这个事件。而上游在出错事件后发送的“Jerry帅炸天！！！”饼干事件，同样也只是把事件发送了处理，下游订单销售并没有接收处理这个事件。

运行后输出结果： 

细心的小伙伴应该会发现，每次执行的时候都会先调用下游的onSubscribe方法，这个方法里有个参数Disposable（用完即可丢弃）意思可以理解成，将上下游的连接切断，让上游的生产的饼干不打包放入下游订单销售环节，实际开发中是有这种需求的，当发送事件出问题的时候就需要断开事件接收处理。不像最近的疫苗事件，一些不要脸的生物疫苗公司把生产不合格的疫苗上市销售，伤天害理，谋财害命。下面举个例子：
    
    
    public void test3() {
    
            // 上游生成产品流水线
            Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
                @Override
                public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                    Log.d(TAG, "test3 ====== Observable: ------ onNext: Jerry");
                    emitter.onNext("Jerry");
                    Log.d(TAG, "test3 ====== Observable: ------ onNext: 就是");
                    emitter.onNext("就是");
                    Log.d(TAG, "test3 ====== Observable: ------ onNext: 帅");
                    emitter.onNext("帅");
                    Log.d(TAG, "test3 ====== Observable: ------ onNext: ！！！");
                    emitter.onNext("！！！");
                    Log.d(TAG, "test3 ====== Observable: ------ onComplete");
                    emitter.onComplete();
                    Log.d(TAG, "test3 ====== Observable: ------ onNext: Jerry帅炸天！！！");
                    emitter.onNext("Jerry帅炸天！！！");
                }
            });
    
            // 下游订单产品销售
            Observer<String> observer = new Observer<String>() {
    
                private Disposable mDisposable;
                private int i;
    
                @Override
                public void onSubscribe(Disposable d) {
                    Log.d(TAG, "test3 ====== Observer: onSubscribe");
                    mDisposable = d;
                }
    
                @Override
                public void onNext(String value) {
                    Log.d(TAG, "test3 ====== Observer: onNext: " + value);
                    i++;
                    // 第一个事件接收后，就断开上下游连接
                    if (i == 1) {
                        Log.d(TAG, "test3 ====== Observer: start disposable");
                        mDisposable.dispose();
                        Log.d(TAG, "test3 ====== Observer: isDisposable: " + mDisposable.isDisposed());
                    }
                }
    
                @Override
                public void onError(Throwable e) {
                    Log.d(TAG, "test3 ====== Observer: onError: " + e.getMessage());
                }
    
                @Override
                public void onComplete() {
                    Log.d(TAG, "test3 ====== Observer: onComplete");
                }
            };
    
            // 连接上下游的订单管理系统
            observable.subscribe(observer);
        }
    复制代码

这里我们在下游订单销售的onNext方法中，当接收完第一个饼干事件后，就使用mDisposable.dispose()方法将上下游的连接断开了，断开后上游后续生产的饼干事件，下游就接收不到。

运行的结果： 

上图中，也验证了我们的猜想，当使用dispose断开上下游连接后，下游就无法再继续接收事件了。

这一讲就先介绍这么多，这样的方式理解Observable和Observer以及订阅动作subscribe是不是容易多了，希望对你有所帮助，下一讲使用RxJava来切换变化饼干事件处理的线程（主线程、子线程）。