抱著陌生的態(tài)度再看Rxjava(一)

把它當(dāng)做陌生人再一次去認(rèn)識(shí)

環(huán)境集成

首先廢話不多說(shuō),先把Rxjava集成到我們項(xiàng)目中來(lái)兑障。

rxjava1和rxjava2

當(dāng)你在app項(xiàng)目的module setting中添加dependency的時(shí)候,會(huì)出現(xiàn)讓你選擇使用rx1還是2的窘境呈宇,那1和2有什么不一樣呢
在此涂滴,作為并沒(méi)有對(duì)rxjava有所了解的陌生者胆建,我先告訴你,2是1的improvement兼丰,所以我們集成的時(shí)候使用 2即可玻孟。

    compile 'io.reactivex.rxjava2:rxjava:2.0.6'

OK,環(huán)境配置算是完成了。

先隨便擼一段代碼看看

首先你需要普及一段知識(shí)鳍征,這個(gè)所謂的rxjava是基于觀察者模式黍翎,或者子通俗一點(diǎn),你總歸聽(tīng)說(shuō)這玩意兒使用來(lái)做響應(yīng)式編程的吧艳丛。
那么我接下去匣掸,所要寫(xiě)的第一段代碼從Observer和Subscriber開(kāi)始應(yīng)該可以理解了吧
  • Observer

在MainActivity中直接開(kāi)了一個(gè)private的方法,寫(xiě)上Observer质礼,選擇reactx的包旺聚,發(fā)現(xiàn)需要輸入一個(gè)泛型,先什么都不管眶蕉,我們輸入一個(gè)String砰粹,然后new之后自動(dòng)跳出來(lái)一大坨如下:

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

            }
        };

我們點(diǎn)到Observer的源碼看,發(fā)現(xiàn)這個(gè)“觀察者”是個(gè)接口造挽,總共就上述的四個(gè)方法碱璃,具體用來(lái)干什么我們先放一放。

  • Subscriber

國(guó)內(nèi)的rxjava魚(yú)龍混雜饭入,絕大部分是基于rxjava1去進(jìn)行講解的嵌器,你就會(huì)發(fā)現(xiàn)他們會(huì)跟你這么講

Subscriber和Observer是一樣的接口,唯一不同的是谐丢,它里面有自己的兩個(gè)獨(dú)有的方法爽航,onStart蚓让,unSubscribe方法

結(jié)果你在聽(tīng)信了我的話導(dǎo)入了rxjava2之后發(fā)現(xiàn)結(jié)果是這樣的:

Subscriber<String> subscriber = new Subscriber<String>() {
            @Override
            public void onSubscribe(Subscription s) {

            }

            @Override
            public void onNext(String s) {

            }

            @Override
            public void onError(Throwable t) {

            }

            @Override
            public void onComplete() {

            }
        };

沒(méi)錯(cuò),跟Observer一模一樣讥珍,你疑惑的點(diǎn)到源碼里面看历极,發(fā)現(xiàn)也是一模一樣。完全一樣的接口衷佃,完全一樣的四個(gè)接口方法趟卸。

這里我要告訴你,在rxjava1中確實(shí)是Subscriber這個(gè)類存在(rxjava1主包名為rx氏义,rxjava2主包名為io.reactivex)锄列,存在于rx包下,但是我們?cè)?code>io.reactivex包下卻沒(méi)有發(fā)現(xiàn)Subscriber惯悠,我們使用的Subscriber實(shí)際上來(lái)自于org.reactivestreams.Subscriber,rxjava2已經(jīng)將Subscriber這個(gè)抽象類移除了邻邮,代替它的是具體的Subscriber,在io.reactivex.subscribers包下的比如DefaultSubscriber, ResourceSubscriberDisposableSubscriber等抽象類。

  • Observable

當(dāng)我們?cè)谇懊嫦胍獎(jiǎng)?chuàng)建Observer的時(shí)候克婶,IDE會(huì)跳出來(lái)Observable饶囚,字面翻譯的意思是觀察者的東西,猜測(cè)應(yīng)該是用來(lái)傳遞的對(duì)象鸠补,我們來(lái)看一下,進(jìn)到源碼中我們發(fā)現(xiàn)嘀掸,這個(gè)Observable是個(gè)抽象類紫岩,那照理來(lái)說(shuō)應(yīng)該是被繼承而非直接創(chuàng)建實(shí)例才對(duì)。

這種時(shí)候我們一般怎么做睬塌,大家知道我們通常不去使用抽象類new對(duì)象泉蝌,那么如果這個(gè)抽象類有其他的一些構(gòu)造方法,肯定就是在static方法中揩晴,結(jié)果我們發(fā)現(xiàn)他有個(gè)create方法勋陪,上面的注釋下的很明白,將相應(yīng)與回調(diào)聯(lián)系起來(lái)的一個(gè)API硫兰,我們不妨用用看

Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                
            }
        });

我們可以看到create方法對(duì)傳參的描述

the emitter that is called when an Observer subscribes to the returned

翻譯成人話的意思是當(dāng)觀察者訂閱了之后所回調(diào)的一個(gè)發(fā)射器(這里的發(fā)射器我們就把他理解成一個(gè)相當(dāng)迅速的回調(diào))诅愚,我們?cè)賮?lái)看一下這個(gè)ObservableOnSubscribe接口,按照之前的理解劫映,他就是觀察者做了訂閱動(dòng)作之后返回的一個(gè)回調(diào)违孝。
只有一個(gè)接口方法:

/**
     * Called for each Observer that subscribes.
     * @param e the safe emitter instance, never null
     * @throws Exception on error
     */
    void subscribe(ObservableEmitter<T> e) throws Exception;

我們看到每一個(gè)觀察者訂閱了之后都會(huì)觸發(fā)這個(gè)subscribe方法

繼續(xù)看這個(gè)ObservableEmitter,觀察者發(fā)射器泳赋,繼承Emitter雌桑,就是發(fā)射器,一看是個(gè)接口祖今,接口里面有三個(gè)方法校坑,onNext拣技,onError, onComplete。是不是有點(diǎn)印象耍目,沒(méi)錯(cuò)跟之前的Observer和Subscriber接口的方法一模一樣膏斤。

那好,根據(jù)之前的注釋和接口里的方法制妄,我們可以篤定掸绞,這幾個(gè)類之間一定是有關(guān)系的,主要是怎么把他們聯(lián)系起來(lái)耕捞。

  • 把Observable衔掸,Observer,Subscriber聯(lián)系起來(lái)
    由于ObserverSubscriber都是接口俺抽,方法又都只有四個(gè)且都是onXXX這種非主動(dòng)性方法敞映,那我們只有從Observable入手,我們開(kāi)始在Observable方法中全局搜索Observer類磷斧,看哪個(gè)方法的傳參類型是Observer振愿,發(fā)現(xiàn):
    public final void subscribe(Observer<? super T> observer) 

但是沒(méi)有發(fā)現(xiàn)Subscriber。不管了弛饭,我們先用用看冕末,我們?cè)趧偛诺腛bserver和Observable的方法中打上log。

Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext("hello on next");
                Log.e("observable", "subscribe    ");
            }
        });

結(jié)果發(fā)現(xiàn)侣颂,subscribe方法內(nèi)調(diào)什么档桃,Observer就回調(diào)什么。

OK憔晒,這兩者的關(guān)系已經(jīng)很明顯了藻肄。那么到底Subscriber是和誰(shuí)聯(lián)系起來(lái)的呢

  • Flowable橫空出世

    想來(lái)想去不知道Subscriber被誰(shuí)用,你如果之前不知道Rxjava拒担,再或者你即使用過(guò)Rxjava1嘹屯,到了這兒你也不知道怎么去用Subscriber。

    無(wú)奈从撼,點(diǎn)開(kāi)了github的Rxjava2目錄州弟,你會(huì)在包的根目錄中發(fā)現(xiàn)如下四個(gè)跟Observable很像的類,分別是Completable谋逻,F(xiàn)lowable呆馁,Maybe,Single毁兆。


    Observable.png

    Completable.png

    Flowable.png

    Maybe.png

    Single.png

    我們?nèi)ヒ粋€(gè)一個(gè)的看這幾個(gè)類的subscribe方法浙滤,我們會(huì)發(fā)現(xiàn)Completable對(duì)應(yīng)的傳參是onComplete的actionSingle對(duì)應(yīng)的是SingleObserver气堕,Maybe對(duì)應(yīng)的是MaybeObserver纺腊,Flowable對(duì)應(yīng)的是Subscriber畔咧。終于找到了!R灸ぁ誓沸!趕緊拿來(lái)用一用。

Flowable<String> flowable = Flowable.create(new FlowableOnSubscribe<String>() {
            @Override
            public void subscribe(FlowableEmitter<String> e) throws Exception {
                e.onNext("hello flowable1");
            }
        }, BackpressureStrategy.DROP);
flowable.subscribe(subscriber);

效仿Observable的構(gòu)造方法壹粟,我們同樣用create去創(chuàng)建Flowable對(duì)象拜隧,new了之后IDE幫我們自動(dòng)生成,結(jié)果發(fā)現(xiàn)傳參有兩個(gè)趁仙,我們點(diǎn)到create方法中看到還需要傳一個(gè)BackpressureStrategy洪添。。雀费。

這是個(gè)啥

點(diǎn)開(kāi)BackpressureStrategy干奢,發(fā)現(xiàn)是個(gè)enum,先不管那么多了隨便傳一個(gè)進(jìn)去看看盏袄,我就用了BackpressureStrategy.DROP忿峻。

發(fā)現(xiàn),發(fā)現(xiàn)辕羽,什么都沒(méi)出來(lái)9渖小!

不過(guò)刁愿,我不管了黑低,我把這個(gè)關(guān)系給找出來(lái)已經(jīng)很累了,先歇會(huì)兒酌毡,喝杯茶~~~

  • 關(guān)于onNext,onError蕾管,onComplete要說(shuō)的一些話
    • 你可以在Subscribe方法(我們可以稱之為上游)中發(fā)送無(wú)限個(gè)onNext枷踏,在onSubScribe方法中(我們稱之為下游)就可以接受無(wú)限個(gè)onNext。
    • 但是倘若你在上游發(fā)送了onComplete掰曾,或者是onError之后旭蠕,下游接受到了,上游之后的事件下游就不再接受了旷坦。(這個(gè)想想就可以理解)
    • onComplete和onError是互相排斥的掏熬,你不能在上游發(fā)了onComplete之后又發(fā)onError,當(dāng)然你發(fā)了下游也接受不到秒梅,hohoho~
    • 你不能發(fā)送多個(gè)onComplete和多個(gè)onError旗芬,雖然后續(xù)都不會(huì)再接受。但是要注意哦捆蜀。發(fā)送多個(gè)onComplete系統(tǒng)不會(huì)崩潰疮丛,發(fā)送多個(gè)onError幔嫂,你試試~~
  • Disposable,Subscription怎么用呢
    • Disposable
      我們?cè)谏厦嬷vObserver的時(shí)候并沒(méi)有涉及到Disposable的用法誊薄,我們點(diǎn)到這個(gè)類里看一下

/**

  • Represents a disposable resource.
    /
    public interface Disposable {
    /
    *

    • Dispose the resource, the operation should be idempotent.
      */
      void dispose();

    /**

    • Returns true if this resource has been disposed.
    • @return true if this resource has been disposed
      */
      boolean isDisposed();
      }
   是個(gè)接口履恩,只有兩個(gè)方法,Disposable字面意思是一次性東西呢蔫。dispose我們看到注釋是處理這個(gè)資源切心,操作等冪。

   這個(gè)`idempotent`是什么鬼片吊,這個(gè)詞語(yǔ)之后可能會(huì)在注釋中一直看見(jiàn)绽昏,表示這個(gè)方法你使用多次跟使用一次的效果是一樣的。

   其實(shí)很好理解定鸟,dispose就是銷毀這個(gè)資源而涉,如果放在響應(yīng)式編程中,我猜联予,算了啼县,不猜了,意思再明顯不過(guò)了沸久,就是斷開(kāi)觀察者和被觀察者之間的關(guān)系季眷。也就是說(shuō)接下去下游不會(huì)再收到上游的任何通知。

   使用過(guò)程中我們需要注意什么呢卷胯?

   如果我們的activity已經(jīng)退出了子刮,如果上游和下游還連著,下游如果做UI改動(dòng)窑睁,會(huì)導(dǎo)致程序崩潰挺峡。
    我們需要在onSubscribe中將Disposable進(jìn)行緩存,然后在activity退出的時(shí)候担钮,調(diào)用它的Disposable.dispose方法斷開(kāi)連接橱赠。如果有多個(gè)Disposable,那我們可以使用官方提供的容器類`CompositeDisposable`箫津,這個(gè)類提供了add和clear方法狭姨,可以對(duì)Disposable群體進(jìn)行管理。
   * Subscription
    記得前面講Flowable的時(shí)候苏遥,什么東西都沒(méi)有出來(lái)么饼拍,現(xiàn)在看看好像只能從這個(gè)家伙入手了,讓我們一起點(diǎn)開(kāi)它的源碼看個(gè)究竟田炭。
   
     一看师抄,是個(gè)接口,只有兩個(gè)方法教硫,一個(gè)`request`,一個(gè)`cancel`司澎。我又要猜了欺缘,一個(gè)是請(qǐng)求,一個(gè)是斷開(kāi)挤安。但是request后面還會(huì)跟著一個(gè)參數(shù)谚殊,這什么意思呢?

    來(lái)看下它的parm解釋蛤铜,大體翻譯成老百姓看的懂得意思就是接受上游的事件數(shù)嫩絮,你上游可以發(fā)很多事件,但是我這里就接受那么多個(gè)围肥,接下去的我不接受剿干。
 
    我們?cè)赟ubscriber的onSubscribe方法中添加  `subscription.request(2)`這行代碼。(隨便寫(xiě)了個(gè)2)穆刻,然后程序一跑置尔,發(fā)現(xiàn)onNext打印出來(lái)了。

     在經(jīng)過(guò)各種組合打印之后氢伟,最終得出的結(jié)論是榜轿,request傳入的個(gè)數(shù)是接受的onNext的個(gè)數(shù),onComplete和onError不算在接受事件的個(gè)數(shù)之中朵锣。

* #####subscribe方法的重載
   無(wú)論是Observable或者是flowable谬盐,他們的subscrib方法都有相同的重載
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/Subscriber<? super T> observer/subscriber) {}
   幾個(gè)重載的意思分別是,什么都不監(jiān)聽(tīng)诚些,就是只管上游發(fā)事件飞傀,沒(méi)有監(jiān)聽(tīng)的下游;只監(jiān)聽(tīng)onNext方法诬烹,其他不監(jiān)聽(tīng)砸烦;只監(jiān)聽(tīng)onNext和onError;绞吁。外冀。。

-------

##電梯
  [抱著陌生的態(tài)度再看Rxjava(二)](http://www.reibang.com/p/f435dc51221f)
    [抱著陌生的態(tài)度再看Rxjava(三)](http://www.reibang.com/p/96df60fd35c6)
    [抱著陌生的態(tài)度再看Rxjava(四)](http://www.reibang.com/p/de8af3fadede)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末掀泳,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子西轩,更是在濱河造成了極大的恐慌员舵,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件藕畔,死亡現(xiàn)場(chǎng)離奇詭異马僻,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)注服,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)韭邓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)措近,“玉大人,你說(shuō)我怎么就攤上這事女淑〔t郑!?“怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵鸭你,是天一觀的道長(zhǎng)屈张。 經(jīng)常有香客問(wèn)我,道長(zhǎng)袱巨,這世上最難降的妖魔是什么阁谆? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮愉老,結(jié)果婚禮上场绿,老公的妹妹穿的比我還像新娘。我一直安慰自己嫉入,他們只是感情好焰盗,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著劝贸,像睡著了一般姨谷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上映九,一...
    開(kāi)封第一講書(shū)人閱讀 49,741評(píng)論 1 289
  • 那天梦湘,我揣著相機(jī)與錄音,去河邊找鬼件甥。 笑死捌议,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的引有。 我是一名探鬼主播瓣颅,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼譬正!你這毒婦竟也來(lái)了宫补?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤曾我,失蹤者是張志新(化名)和其女友劉穎粉怕,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體抒巢,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贫贝,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片稚晚。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡崇堵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出客燕,到底是詐尸還是另有隱情鸳劳,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布幸逆,位于F島的核電站棍辕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏还绘。R本人自食惡果不足惜楚昭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拍顷。 院中可真熱鬧抚太,春花似錦、人聲如沸昔案。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)踏揣。三九已至庆亡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捞稿,已是汗流浹背又谋。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留娱局,地道東北人彰亥。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像衰齐,于是被迫代替她去往敵國(guó)和親任斋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

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