RxJava 2 源碼分析(一)

在分析之前呢,首先需要大家打開源碼對照分析榜旦。效果更加S钠摺!

首先我們看一下RxJava 2 三步曲的一個基本實(shí)現(xiàn):
1 創(chuàng)建被觀察者(也叫數(shù)據(jù)發(fā)射者)
2 創(chuàng)建觀察者(也叫數(shù)據(jù)消費(fèi)者)
3 建立訂閱關(guān)系

代碼如下:

    //第一步 創(chuàng)建被觀察者
    Observable<String> observable = Observable.create(
            new ObservableOnSubscribe<String>() {
                @Override
                public void subscribe(ObservableEmitter<String> e) throws Exception {

                    e.onNext("發(fā)射數(shù)據(jù)");
                    e.onComplete();
                }
            }
    );

    //第二步 創(chuàng)建觀察者
    Observer<String> observer = new Observer<String>() {

        private Disposable disposable;

        @Override
        public void onSubscribe(Disposable d) {
            disposable = d;
        }

        @Override
        public void onNext(String value) {

        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onComplete() {

        }
    };

    //第三步 建立訂閱關(guān)系
    observable.subscribe(observer);

新記:
我們來看一下創(chuàng)建Observable的這個靜態(tài)方法create.實(shí)際上這個是RxJava大量的操作符中的一個溅呢,create方法會返回一個Observable實(shí)例澡屡。
create方法的參數(shù)是一個實(shí)現(xiàn)了ObservableOnSubscribe接口的對象實(shí)例,該接口提供了發(fā)射數(shù)據(jù)的回調(diào)subscribe()方法,回調(diào)回來的ObservableEmitter實(shí)例就可以看成是數(shù)據(jù)發(fā)射器咐旧,用來發(fā)射數(shù)據(jù)驶鹉。

我們來看看Observable.create()的內(nèi)部實(shí)現(xiàn):

public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
    ObjectHelper.requireNonNull(source, "source is null");
    return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}

首先是創(chuàng)建了一個ObservableCreate實(shí)例,是Observable的子類铣墨,把之前參數(shù)中創(chuàng)建的ObservableOnSubscribe實(shí)例直接傳了進(jìn)去室埋,作了件什么事呢?實(shí)際上實(shí)現(xiàn)了一個代理的作用,代理的是誰姚淆?是Observer孕蝉,后面我們再詳細(xì)分析,我們可以確定腌逢,ObservableCreate就是一個Observable降淮。
我們再看RxJavaPlugins.onAssembly().這個方法拿了ObservableCreate(Observable)實(shí)例去做了什么:

public static <T> Observable<T> onAssembly(Observable<T> source) {
    Function<Observable, Observable> f = onObservableAssembly;
    if (f != null) {
        return apply(f, source);
    }
    return source;
}

RxJavaPlugins這個類是一個鉤子函數(shù)集合類,為RxJava中大量的操作符提供鉤子函數(shù)的注入搏讶。這里的鉤子函數(shù)會對Observable實(shí)例按照鉤子函數(shù)實(shí)際提供的功能進(jìn)行加工處理佳鳖,然后返回一個處理過的Observable。實(shí)際上在我們上面所寫的這個代碼示例中媒惕,這里的鉤子函數(shù)為null系吩,并沒有對Observable做任何處理就直接返回了。

實(shí)際上我們示例代碼中整個被觀察者Observable的創(chuàng)建吓笙,實(shí)際創(chuàng)建的是一個ObservableCreate實(shí)例淑玫,該實(shí)例提供了回調(diào)方法subscribe(),當(dāng)發(fā)生訂閱行為時(shí)會回調(diào)面睛,也就是示例代碼中執(zhí)行observable.subscribe(),訂閱后就可以發(fā)射數(shù)據(jù)了絮蒿。通過數(shù)據(jù)發(fā)射器ObservableEmitter來進(jìn)行數(shù)據(jù)發(fā)射。

像這種訂閱后才開始發(fā)射數(shù)據(jù)的叁鉴,我們稱為Cold Observable土涝; 另外一種稱作Hot Observable,這種是不管有沒有觀察者來訂閱都會不斷地發(fā)射數(shù)據(jù)。

我們再來看看observable.subscribe()訂閱的內(nèi)部代碼:

  public final void subscribe(Observer<? super T> observer) {
    ObjectHelper.requireNonNull(observer, "observer is null");
    try {
        observer = RxJavaPlugins.onSubscribe(this, observer);

        ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");

        subscribeActual(observer);
    ...//這里把不關(guān)心的代碼省略掉了
}

首先是代碼中的RxJavaPlugins.onSubscribe()的調(diào)用與上面講的鉤子方法是一樣的幌墓,這里是通過鉤子方法對observer作了某種處理但壮。示例中實(shí)際上也并未調(diào)用實(shí)際的鉤子方法。

最后就執(zhí)行到了subscribeActual()方法常侣,我們前面講過我們的Observable是一個ObservableCreate實(shí)例蜡饵,subscribeActual方法在Observable中是一個虛方法,真正的實(shí)現(xiàn)是在ObservableCreate中胳施,代碼如下:

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

代碼中的CreateEmitter是ObservableCreate的內(nèi)部類溯祸,實(shí)現(xiàn)了對observer的代理,CreateEmitter同時(shí)也實(shí)現(xiàn)了Disposable接口舞肆,該接口提供了dispose方法焦辅,可以用來停止對數(shù)據(jù)的接收。
我們接下來再看后面的幾行代碼就很明了了椿胯,首先是進(jìn)行了observer的onSubscribe回調(diào)筷登,然后是調(diào)用了observable的subscribe回調(diào),回調(diào)后就執(zhí)行數(shù)據(jù)發(fā)射操作哩盲。
整個過程就這樣前方。

最后狈醉,我們來看一下執(zhí)行的順序:

整個執(zhí)行順序
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市惠险,隨后出現(xiàn)的幾起案子舔糖,更是在濱河造成了極大的恐慌,老刑警劉巖莺匠,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異十兢,居然都是意外死亡趣竣,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進(jìn)店門旱物,熙熙樓的掌柜王于貴愁眉苦臉地迎上來遥缕,“玉大人,你說我怎么就攤上這事宵呛〉ハ唬” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵宝穗,是天一觀的道長户秤。 經(jīng)常有香客問我,道長逮矛,這世上最難降的妖魔是什么鸡号? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮须鼎,結(jié)果婚禮上鲸伴,老公的妹妹穿的比我還像新娘。我一直安慰自己晋控,他們只是感情好汞窗,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著赡译,像睡著了一般仲吏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上捶朵,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天蜘矢,我揣著相機(jī)與錄音,去河邊找鬼综看。 笑死品腹,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的红碑。 我是一名探鬼主播舞吭,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼泡垃,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了羡鸥?” 一聲冷哼從身側(cè)響起蔑穴,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惧浴,沒想到半個月后存和,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡衷旅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年捐腿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片柿顶。...
    茶點(diǎn)故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡茄袖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出嘁锯,到底是詐尸還是另有隱情宪祥,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布家乘,位于F島的核電站蝗羊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏烤低。R本人自食惡果不足惜肘交,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望扑馁。 院中可真熱鬧涯呻,春花似錦、人聲如沸腻要。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽雄家。三九已至效诅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間趟济,已是汗流浹背乱投。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留顷编,地道東北人戚炫。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像媳纬,于是被迫代替她去往敵國和親双肤。 傳聞我的和親對象是個殘疾皇子施掏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評論 2 349

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

  • 本篇文章介主要紹RxJava中操作符是以函數(shù)作為基本單位,與響應(yīng)式編程作為結(jié)合使用的茅糜,對什么是操作七芭、操作符都有哪些...
    嘎啦果安卓獸閱讀 2,851評論 0 10
  • 注:只包含標(biāo)準(zhǔn)包中的操作符,用于個人學(xué)習(xí)及備忘參考博客:http://blog.csdn.net/maplejaw...
    小白要超神閱讀 2,186評論 2 8
  • 我從去年開始使用 RxJava 蔑赘,到現(xiàn)在一年多了狸驳。今年加入了 Flipboard 后,看到 Flipboard 的...
    Jason_andy閱讀 5,460評論 7 62
  • 參考:給 Android 開發(fā)者的 RxJava 詳解-扔物線深入淺出RxJava 基礎(chǔ) "a library f...
    Vincen1024閱讀 541評論 0 1
  • 作者寄語 很久之前就想寫一個專題缩赛,專寫Android開發(fā)框架锌历,專題的名字叫 XXX 從入門到放棄 ,沉淀了這么久峦筒,...
    戴定康閱讀 7,616評論 13 85