用RxJava2 顯示/隱藏loading的優(yōu)雅方式

本文主要探究用Rxjava2 + Retrofit進(jìn)行網(wǎng)絡(luò)請(qǐng)求時(shí), 應(yīng)該在哪里調(diào)用 showLoading(), 在哪里調(diào)用 hideLoading().

別告訴我, 你是這樣調(diào)用的....

//網(wǎng)絡(luò)請(qǐng)求獲取用戶信息
showLoading();
API.getUserInfo()
       ....
       .subscribe((integer -> {
            hideLoading();
            //dosomething
              ...
       }, e -> {  
            hideLoading();
            //handle error
            ...
       });

當(dāng)然也無(wú)妨, 只不過(guò)丑了點(diǎn)... 這里, 我們用doXXX 操作符優(yōu)雅的解決這個(gè)問(wèn)題.

首先探究下各種 doXXX 操作符的執(zhí)行時(shí)機(jī): (類似于聲明周期)

1. 正常執(zhí)行

測(cè)試代碼

            Observable.create(emiter -> {
                emiter.onNext(1);
                emiter.onComplete();
            })
                    .doOnSubscribe(d -> LOG.d(TAG, "doOnSubscribe"))
                    .doOnNext(integer -> LOG.d(TAG, "doOnNext"))
                    .doAfterNext(integer -> LOG.d(TAG, "doAfterNext"))
                    .doOnComplete(() -> LOG.d(TAG, "doOnComplete"))
                    .doOnError(throwable -> LOG.d(TAG, "doOnError"))
                    .doOnTerminate(() -> LOG.d(TAG, "doOnTerminate"))
                    .doAfterTerminate(() -> LOG.d(TAG, "doAfterTerminate"))
                    .doFinally(() -> LOG.d(TAG, "doFinally"))
                    .doOnDispose(() -> LOG.d(TAG, "doOnDispose"))
                    .subscribe(integer -> {
                        LOG.d(TAG, "onNext");
                    }, e -> {
                        LOG.d(TAG, "onError");
                    }, () -> {
                        LOG.d(TAG, "onComplete");
                    });

結(jié)果

        // doOnSubscribe
        // doOnNext
        // onNext
        // doAfterNext
        // doOnComplete
        // doOnTerminate
        // onComplete
        // doFinally
        // doAfterTerminate

2. 上游拋異常

測(cè)試代碼

            Observable.create(emiter -> {
                emiter.onError(new NullPointerException());
            })
                    .doOnSubscribe(d -> LOG.d(TAG, "doOnSubscribe"))
                    .doOnNext(integer -> LOG.d(TAG, "doOnNext"))
                    .doAfterNext(integer -> LOG.d(TAG, "doAfterNext"))
                    .doOnComplete(() -> LOG.d(TAG, "doOnComplete"))
                    .doOnError(throwable -> LOG.d(TAG, "doOnError"))
                    .doOnTerminate(() -> LOG.d(TAG, "doOnTerminate"))
                    .doAfterTerminate(() -> LOG.d(TAG, "doAfterTerminate"))
                    .doFinally(() -> LOG.d(TAG, "doFinally"))
                    .doOnDispose(() -> LOG.d(TAG, "doOnDispose"))
                    .subscribe((integer -> {
                        LOG.d(TAG, "onNext");
                    }, e -> {
                        LOG.d(TAG, "onError");
                    }, () -> {
                        LOG.d(TAG, "onComplete");
                    }));

結(jié)果

        // doOnSubscribe
        // doOnError
        // doOnTerminate
        // onError
        // doFinally
        // doAfterTerminate

根據(jù)以上執(zhí)行結(jié)果可以看出, 不管是正常執(zhí)行還是上游拋出異常,
開始都會(huì)調(diào)用 doOnSubscribe,
結(jié)束都會(huì)調(diào)用 doOnTerminate, doFinally, doAfterTerminate .

那么是不是我們可以從以上三個(gè)方法中隨便選一個(gè)作為結(jié)束的節(jié)點(diǎn), 調(diào)用hideLoading()就可以呢?
非也! 下面來(lái)看一個(gè)很多人容易忽略的問(wèn)題, 在下游的 onNext() 方法中拋出異常,

3. 下游 onNext 拋異常

測(cè)試代碼

Observable.create(emiter -> {
    emiter.onNext(1);
    emiter.onComplete();
})
    .doOnSubscribe(d -> LOG.d(TAG, "doOnSubscribe"))
    .doOnNext(integer -> LOG.d(TAG, "doOnNext"))
    .doAfterNext(integer -> LOG.d(TAG, "doAfterNext"))
    .doOnComplete(() -> LOG.d(TAG, "doOnComplete"))
    .doOnError(throwable -> LOG.d(TAG, "doOnError"))
    .doOnTerminate(() -> LOG.d(TAG, "doOnTerminate"))
    .doAfterTerminate(() -> LOG.d(TAG, "doAfterTerminate"))
    .doFinally(() -> LOG.d(TAG, "doFinally"))
    .doOnDispose(() -> LOG.d(TAG, "doOnDispose"))
    .subscribe(integer -> {
        LOG.d(TAG, "onNext");
        throw new NullPointerException();  //此處拋出異常
    }, e -> {
        LOG.d(TAG, "onError");
    }, () -> {
        LOG.d(TAG, "onComplete");
    });

結(jié)果

        // doOnSubscribe
        // doOnNext
        // onNext
        // doOnDispose
        // doFinally
        // onError
        // doAfterNext

onNext()中拋出異常就是你的業(yè)務(wù)邏輯中報(bào)錯(cuò)了, 此時(shí)會(huì)調(diào)用onError(), 但不會(huì)調(diào)用doOnError, doOnTerminatedoAfterTerminate.
所以如果你選擇了doOnTerminate 或者 doAfterTerminate 作為了你的結(jié)束節(jié)點(diǎn), 那么就可能會(huì)出現(xiàn)loading顯示后無(wú)法隱藏的問(wèn)題..

綜上, 我們找到了整個(gè)事件的首尾節(jié)點(diǎn):
開始必然執(zhí)行 doOnSubscribe
結(jié)束必然執(zhí)行 doFinally

優(yōu)雅的方式:

//網(wǎng)絡(luò)請(qǐng)求獲取用戶信息
API.getUserInfo()
       .doOnSubscribe(d -> showLoading())
       .doFinally(() -> hideLoading())
       .subscribe((integer -> {
             //dosomething
       }, e -> {  
            //handle error
       });
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末柴信,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌共螺,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異膜楷,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)贞奋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門赌厅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人轿塔,你說(shuō)我怎么就攤上這事特愿。” “怎么了勾缭?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵揍障,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我俩由,道長(zhǎng)毒嫡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任幻梯,我火速辦了婚禮兜畸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘碘梢。我一直安慰自己咬摇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布煞躬。 她就那樣靜靜地躺著肛鹏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上龄坪,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音复唤,去河邊找鬼健田。 笑死,一個(gè)胖子當(dāng)著我的面吹牛佛纫,可吹牛的內(nèi)容都是我干的妓局。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼呈宇,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼好爬!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起甥啄,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤存炮,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后蜈漓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體穆桂,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年融虽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了享完。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡有额,死狀恐怖般又,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情巍佑,我是刑警寧澤茴迁,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站句狼,受9級(jí)特大地震影響笋熬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜腻菇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一胳螟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧筹吐,春花似錦糖耸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春舍扰,著一層夾襖步出監(jiān)牢的瞬間倦蚪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工边苹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留陵且,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓个束,卻偏偏與公主長(zhǎng)得像慕购,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子茬底,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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

  • 怎么如此平靜, 感覺(jué)像是走錯(cuò)了片場(chǎng).為什么呢, 因?yàn)樯舷掠喂ぷ髟谕粋€(gè)線程呀騷年們! 這個(gè)時(shí)候上游每次調(diào)用emit...
    Young1657閱讀 1,466評(píng)論 2 1
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理沪悲,服務(wù)發(fā)現(xiàn),斷路器阱表,智...
    卡卡羅2017閱讀 134,651評(píng)論 18 139
  • 前言 如果你對(duì)RxJava1.x還不是了解殿如,可以參考下面文章。 1. RxJava使用介紹 【視頻教程】2. Rx...
    jdsjlzx閱讀 21,169評(píng)論 3 78
  • 這個(gè)頁(yè)面展示的操作符可用于組合多個(gè) Observables捶枢。 Delay — 延時(shí)發(fā)射 Observable 的結(jié)...
    DoubleThunder閱讀 3,023評(píng)論 0 3
  • 今天的晨讀是《關(guān)鍵20小時(shí)握截,快速學(xué)會(huì)任何技能》,聽了一遍音頻烂叔,看了一遍TED演講谨胞,再看文章,之后蒜鸡,我去買了一把古...
    青河有花閱讀 218評(píng)論 9 1