Rxjava中onComplete和onError分析

1 上游怎么傳遞onComplete到下游
2 上游怎么傳遞onError到下游
3 它倆是互斥的嗎
4 多次調(diào)用的結(jié)果是什么
5 onNext onSubscribe順便分析一下

示例代碼

Observable.create(new ObservableOnSubscribe<String>() {
            public void subscribe(@NonNull ObservableEmitter<String> emitter)  {
                emitter.onNext("msg");
                String data = null;
                data.length();
                // emitter.onComplete();
                // emitter.onError(new IllegalArgumentException("1"));
            }

        }).subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(String s) {
                Log.d(TAG, s);
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "" + e.getMessage());
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "complete");
            }

        });

先具體分析一下流程

Observable.create.subscribe鏈?zhǔn)秸{(diào)用
Observable.create返回一個(gè)Observable,實(shí)現(xiàn)是ObservableCreate
Observable.subcribe如下粉洼,會(huì)觸發(fā)subcribeActual方法

try {
            observer = RxJavaPlugins.onSubscribe(this, observer);
            subscribeActual(observer);
        } catch (NullPointerException e) { // NOPMD
            throw e;

subscribeActual是抽象的方法,所以針對(duì)操作符create需要看ObservableCreate的
subscribeActual

分析ObservableCreate的subscribeActual

protected void subscribeActual(Observer<? super T> observer) {
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);
        observer.onSubscribe(parent);

        try {
            source.subscribe(parent);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }

先調(diào)用觀察者onSubscribe,然后調(diào)用source的subscribe,也就是如下例子中new ObservableOnSubscribe,接著觸發(fā)emitter.onNext,接著觸發(fā)觀察者的onNext戒突,這也是上游的subscribe怎么通過onNext觸發(fā)到下游的onNext
梳理調(diào)用流程
1 ObservableCreate.subcribe
2 Observable.subscibeActual
3 ObservableOnSubscribe.subscribe
4 CreateEmitter.onNext
5 observer.onNext(t);
所以CreateEmitter就把上游和下游關(guān)聯(lián)起來,
當(dāng)上游調(diào)用subcribeActual就會(huì)出發(fā)CreateEmitter然后調(diào)用下游onNext

Observable.create(new ObservableOnSubscribe<String>() {
            public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext("msg");
        public void onNext(T t) {
            if (!isDisposed()) {
                observer.onNext(t);
            }
        }

并且此操作會(huì)捕捉異常,如果出現(xiàn)異常交給parent.onError(ex),而onError方法觸發(fā)tryOnError方法

        public boolean tryOnError(Throwable t) {
            if (!isDisposed()) {
                try {
                    observer.onError(t);
                } finally {
                    dispose();
                }
                return true;
            }
            return false;
        }

這是程序運(yùn)行拋出異常,也就是調(diào)用顯式的onError:
如果第二次onError顾瞻,就會(huì)判斷當(dāng)前訂閱關(guān)系解除,然后交給RxJavaPlugins.onError(t);如果設(shè)置RxJava統(tǒng)一異常捕捉則交給此處理否則
直接拋出異常德绿;一般為閃退荷荤;

subscribe(Consumer)分析

內(nèi)部轉(zhuǎn)成觀察者Observer

 LambdaObserver<T> ls = new LambdaObserver<T>(onNext, onError, onComplete, onSubscribe);

        subscribe(ls);

在onNext觸發(fā)accept方法

 @Override
    public void onNext(T t) {
        if (!isDisposed()) {
            try {
                onNext.accept(t);
            } catch (Throwable e) {
                Exceptions.throwIfFatal(e);
                get().dispose();
                onError(e);
            }
        }
    }

onComplete調(diào)用也是判斷沒有解除訂閱就finally解除訂閱

if (!isDisposed()) {
                try {
                    observer.onComplete();
                } finally {
                    dispose();
                }
            }

所以調(diào)用一次complete就會(huì)解除訂閱退渗,多次complete就會(huì)失效,因?yàn)檫B接已經(jīng)解除關(guān)系了蕴纳。

onNext

onNext只是判斷有沒有解除上下游關(guān)系会油,并沒有finally里面解除關(guān)聯(lián),所以可以多次調(diào)用

        public void onNext(T t) {
            if (!isDisposed()) {
                observer.onNext(t);
            }
        }

onSubcribe

這個(gè)觀察者觸發(fā)條件只是subcribe觸發(fā)古毛,開發(fā)者無法調(diào)用CreateEmitter也沒有onSubscribe方法

總結(jié):onError調(diào)用一次則解除上下游關(guān)聯(lián)翻翩,如果subscribe內(nèi)部出現(xiàn)異常會(huì)自動(dòng)捕捉傳給下層觀察者的onError;由于調(diào)用一次就會(huì)解除訂閱,第二次調(diào)用交給默認(rèn)Rxjava處理稻薇,默認(rèn)拋出異常出現(xiàn)閃退
onNext則不會(huì)自動(dòng)解除訂閱
onSubcribe內(nèi)部觸發(fā)
onComplete也是第一次觸發(fā)就不會(huì)
先onError后onComplete則由于前一次解除訂閱則后續(xù)onComplete判斷訂閱解除也就不再觸發(fā)
先onComplete后onError則前一次解除訂閱嫂冻,后續(xù)再onError默認(rèn)會(huì)閃退

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市塞椎,隨后出現(xiàn)的幾起案子絮吵,更是在濱河造成了極大的恐慌,老刑警劉巖忱屑,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蹬敲,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡莺戒,警方通過查閱死者的電腦和手機(jī)伴嗡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來从铲,“玉大人瘪校,你說我怎么就攤上這事∶危” “怎么了阱扬?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長伸辟。 經(jīng)常有香客問我麻惶,道長,這世上最難降的妖魔是什么信夫? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任窃蹋,我火速辦了婚禮,結(jié)果婚禮上静稻,老公的妹妹穿的比我還像新娘警没。我一直安慰自己,他們只是感情好振湾,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布杀迹。 她就那樣靜靜地躺著,像睡著了一般押搪。 火紅的嫁衣襯著肌膚如雪树酪。 梳的紋絲不亂的頭發(fā)上浅碾,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音嗅回,去河邊找鬼。 笑死摧茴,一個(gè)胖子當(dāng)著我的面吹牛绵载,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播苛白,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼娃豹,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了购裙?” 一聲冷哼從身側(cè)響起懂版,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎躏率,沒想到半個(gè)月后躯畴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡薇芝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年蓬抄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片夯到。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嚷缭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出耍贾,到底是詐尸還是另有隱情阅爽,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布荐开,位于F島的核電站付翁,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏晃听。R本人自食惡果不足惜胆敞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望杂伟。 院中可真熱鬧移层,春花似錦、人聲如沸赫粥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽越平。三九已至频蛔,卻和暖如春灵迫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晦溪。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工瀑粥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人三圆。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓狞换,卻偏偏與公主長得像,于是被迫代替她去往敵國和親舟肉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子修噪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容