一、初识RxJava2

前言

来随手记实习之前并没有接触过RxJava这个强大的异步处理库,都使用Handler和AsyncTask进行异步任务的处理。但是实习期间跟随我的导师做的主题换肤需求里,基本所有的异步处理都使用了RxJava,并且都已升级到了RxJava2,所以直接从RxJava2.X系列开始对这个强大的异步处理库进行学习。


RxJava的基本工作原理

先上一张“水管”图!!!


RxJava

很多的RxJava文章以观察者模式来进行介绍,但其实有时候太多的专有名词反而会增加我们对一个知识的学习成本。

所以,我们从上图来解释什么是RxJava。

上面的事件流我们称为上游,即Observable

下面的事件流我们称为下游,即Observer

上游和下游的连接就靠subscribe()来建立

上游发出一个事件,下游就要接受并处理这个事件,而且处理的顺序是按上游发出的顺序执行。

实战演练:
讲完“大道理”,我们来“实战”一下:

Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        public void subscribe(ObservableEmitter<String> e) throws Exception {
            e.onNext("Hello");
            e.onNext("World");
            e.onComplete();
        }
    });
 
 
    Observer<String> observer = new Observer<String>() {
        @Override
        public void onSubscribe(Disposable d) {
            Log.d(TAG, "onSubscribe");
        }
 
        @Override
        public void onNext(String s) {
            Log.d(TAG, s);
        }
 
        @Override
        public void onError(Throwable e) {
            Log.d(TAG, "onError");
        }
 
        @Override
        public void onComplete() {
            Log.d(TAG, "onComplete");
        }
    };
 
    observable.subscribe(observer); // 建立连接后才开始发送事件
}

这个的运行结果就是:
运行结果

把上面那段代码连起来写就是RxJava引以为傲的链式调用了:

Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> e) throws Exception {
        e.onNext("Hello");
        e.onNext("World");
        e.onComplete();
    }
}).subscribe(new Observer<String>() {
    @Override
    public void onSubscribe(Disposable d) {
        Log.d(TAG, "onSubscribe");
    }

    @Override
    public void onNext(String s) {
        Log.d(TAG, s);
    }
 
    @Override
    public void onError(Throwable e) {
        Log.d(TAG, "onError");
    }
 
    @Override
    public void onComplete() {
        Log.d(TAG, "onComplete");
    }
});

解释一下里面的两个名词:

ObservableEmitter:
用来发出事件的,它可以发出三种类型的事件,通过调用emitter的:

  1. onNext(T value)发出next事件、
  2. onComplete()发出complete事件
  3. onError(Throwable error)发出error事件。

事件发送的原则:

  1. 上游可以发送无限个onNext事件, 下游也可以接收无限个onNext事件.
  2. 当上游发送了一个onComplete事件后, 上游可以继续发送事件, 而下游收到onComplete事件之后将不再继续接收上游的事件.
  3. 当上游发送了一个onError事件后, 上游onError之后的事件将继续发送, 而下游收到onError事件之后将不再继续接收上游的事件.
  4. 上游可以不发送onComplete或onError事件.
    最为关键的是onComplete和onError必须唯一并且互斥, 即不能发多个5. 5. onComplete, 也不能发多个onError, 也不能先发一个onComplete, 然后再发一个onError, 反之亦然。
发送的关键事件 示意图(队列顺序发送)
只发送onNext事件
onNext
发送onComplete事件
onComplete
发送onError事件
onError

Disposable:
dispose()可以理解成上游和下游的连接断了,当调用dispose()后,下游就会接收不到上游发出的事件。


我们写个小Demo检验一下,上游依次发送1,2,3,4的事件,其中3的任务类型为onComplete()类型,所以下游应该接收不到事件4,可是我们在下游接收到事件1,之后就调用了dispose(),所以不管上游之后发了什么事件,下游都不会收到。

Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> e) throws Exception {
        Log.d(TAG, "1 send");
        e.onNext("1");
         
        Log.d(TAG, "2 send");
        e.onNext("2");
         
        Log.d(TAG, "3 send");
        e.onComplete();
         
        Log.d(TAG, "4 send");
        e.onNext("4");
    }
}).subscribe(new Observer<String>() {
 
    private Disposable disposable;
 
    @Override
    public void onSubscribe(Disposable d) {
        Log.d(TAG, "onSubscribe");
        disposable = d;
    }
 
    @Override
    public void onNext(String s) {
        Log.d(TAG, s + " received");
        if (s.equals("1")) {
            disposable.dispose();
        }
    }
 
    @Override
    public void onError(Throwable e) {
        Log.d(TAG, "onError received");
    }
 
    @Override
    public void onComplete() {
        Log.d(TAG, "onComplete received");
    }
});

让我们来看看执行结果是否符合预期:
输出结果

很明显,在调用了下游在接收到事件1就切断了上游和下游的联系,上游是发送了事件1,2,3,4,可下游只收到了事件1。

其实subscribe()有很多个重载方法:

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) {}

我们之前的用例,全都是用了最后一个方法。
可是有时候我们只关心上游发的onNext事件,不理会其他类型的事件,所以我们可以使用上述第二个重载方法:

Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> e) throws Exception {
        Log.d(TAG, "1 send");
        e.onNext("1");
 
        Log.d(TAG, "2 send");
        e.onNext("2");
 
        Log.d(TAG, "3 send");
        e.onComplete();
 
        Log.d(TAG, "4 send");
        e.onNext("4");
    }
}).subscribe(new Consumer<String>() {
    @Override
    public void accept(String s) throws Exception {
        Log.d(TAG, s + " received");
    }
});

执行结果如下:
输出结果

我们可以看到,下游收到了上游在发出onComplete事件之前的onNext事件。
对于其他几个重载的方法其实大同小异,大家可以自己去动手试试效果。



参考文档:

https://www.jianshu.com/p/464fa025229e

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容