RxJava2 入门食用指南

599 阅读5分钟

RxJava2

这篇只适合 Android 开发者 RxJava 初次食用

放上官方文档, 如果想自己透彻的了解, 还是要翻一翻官方文档

  1. 英文原版
  2. 国内翻译版
  3. 还有个我凯哥(扔物线)的经典教程

凯哥的教程由于是基于 RxJava1 的版本, 在使用上可能会有点区别, 如果看的有点晕就瞅瞅我下面写的吧.

首先加入依赖:

compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
// Because RxAndroid releases are few and far between, it is recommended you also
// explicitly depend on RxJava's latest version for bug fixes and new features.
compile 'io.reactivex.rxjava2:rxjava:2.1.7'

1. 创建和订阅事件

首先理清两个概念:

  1. Observe 观察者
  2. Observable 被观察者

一个观察者(Observer)订阅一个可观察对象(Observable), 观察者对Observable发射的数据或数据序列作出响应。这就是 响应式编程(reactive pattern)

创建一个观察者Observe

        Observer<String> observer = new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                // 可以在此处进行取消订阅的操作
            }

            @Override
            public void onNext(String s) {
                // 这里传入被观察者传入的数据
            }

            @Override
            public void onError(Throwable e) {
                // 处理被观察者的异常
            }

            @Override
            public void onComplete() {
                // 被观察者完成任务后被调用
            }
        };

创建我们的被观察者Observable

创建的方式有很多种:Create, Defer, Empty/Never/Throw, From, Interval, Just, Range, Repeat, Start, and Timer

我们就用简单的 CreateJustFromArray 来做下说明

just代表了传入一系列

简单的 Create 创建需要复写subscribe方法,并手动调用 emitter.onNext() , onError 和 onComplete

        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                try {
                    emitter.onNext(1);
                    emitter.onNext(2);
                    emitter.onNext(3);
                    emitter.onComplete();
                } catch (Exception e) {
                    emitter.onError(e);
                }
            }
        });
  • onNext(T item)

    Observable调用这个方法发射数据,方法的参数就是Observable发射的数据,这个方法可能会被调用多次,取决于你的实现。

  • onError(Exception ex)

    当Observable遇到错误或者无法返回期望的数据时会调用这个方法,这个调用会终止Observable,后续不会再调用onNext和onCompleted,onError方法的参数是抛出的异常。

  • onComplete

    正常终止,如果没有遇到错误,Observable在最后一次调用onNext之后调用此方法。

注意 :

  1. onComplete 和 onError 可以不调用
  2. onNext 可以被调用多次
  3. 传递数据被称为发射,onComplete 和 onError 一般只是通知

产生订阅

observable.subscribe(observer);

一行,是不是很简单?对的,这样就完成了订阅

当然,这肯定不是唯一的订阅模式。

如果你的被观察者想要自己消费掉自己的下游事件,当然也是可行的。

Observable.just(1, 2, 3, 4)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "accept: " + integer);
                    }
                });

捕获异常?事件完成提醒?OK!

Observable.just(1, 2, 3, 4)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "accept: " + integer);
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        // 处理异常
                    }
                }, new Action() {
                    @Override
                    public void run() throws Exception {
                        // onComplete
                    }
                });

2. 线程调度器

其中一个我特别喜欢 RxJava2 的理由就是在线程的切换方面无比的方便和逻辑清晰

mService.getUserInfo("token")
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(new Consumer<UserInfo>() {
                    @Override
                    public void accept(UserInfo userInfo) throws Exception {
                        // 主线程进行 Ui 操作
                    }
                });

通过两个操作符,当然你还不知道操作符为何物,稍微介绍一下,通过使用操作符可以改变一些状态。

这里你就把observeOn() 和 subscribeOn() 理解为用来切换执行线程的操作符

observeOn(Scheduler scheduler)

很多ReactiveX实现都使用调度器 "Scheduler"来管理多线程环境中Observable的转场。你可以使用ObserveOn操作符指定Observable在一个特定的调度器上发送通知给观察者 (调用观察者的onNext, onCompleted, onError方法)。

注意:当遇到一个异常时ObserveOn会立即向前传递这个onError终止通知,它不会等待慢速消费的Observable接受任何之前它已经收到但还没有发射的数据项。这可能意味着onError通知会跳到(并吞掉)原始Observable发射的数据项前面,正如图下展示的。

这个observeOn()如何理解呢,这里我要推荐一下知乎之前搞得分析,讲的已经很清晰了,贴上地址zhihu-rxjava-meetup,非常感谢

杨凡的栗子举的非常好。将每一个observeOn()当场一个弹球的挡板。

每在一个链式调用一个observeOn() 时,就相当于把之前的操作和挡板之后的操作分离开了。挡板之后的操作到下一块挡板所在的线程(不止可以设一个挡板),就是我们 observeOn() 指定的线程。

subscribeOn()

subscribeOn() 表示呢,调度的是最上游到第一块挡板之间的操作,并且只取最上游的那一个。

祭出一张图

一言不合就上图

每一块调度器呢都是一个三角块,小箭头的颜色代表着当前任务的线程,图中的又长又粗的箭头,代表着

它的作用域。

但是对于这样一个使用方式,刚刚的结论就不再适用了。

如果按照刚刚那样分析的话,A() 跑在主线程,B( ), C( ) D( )跑在 IO 线程,但是真的是这样吗?不是

这确是实际上的操作模式,为什么会这样呢

就是因为 flatmap 操作符,实际是切换 Observable 的操作,可以理解为从一个上游切换到另一个上游。这样就把 flatmap 后面的操作执行在主线程上了。类似的操作符还有,deff( ) ,onErrorResumeNext( )

如果我们把 subscribeOn( ) 从 flatmap 里面拿出来,那么就可以按照之前的挡板法去解释,具体看图。

如果想要写出更清晰的代码,我们应该遵循以下两点:

  1. 尽量多用 observerOn()
  2. 保证流里只有一个subscribeOn( ),放在越前面越好

参考:

  1. 知乎 Rxjava-meetup 杨凡
  2. 给 Android 开发者的 RxJava 详解 扔物线

操作符?map,flatmap傻傻分不清?后面这篇文章让你彻底清晰