寫(xiě)給自己的RxJava -- 基礎(chǔ)篇

Rxjava基于觀察者模式忽你,一個(gè)完整的觀察者模式要有三個(gè)角色對(duì)象:觀察者幼东,被觀察者,事件科雳。

而且在異步觀察者模式中根蟹,一般會(huì)有三個(gè)相關(guān)的線程:被觀察者線程(事件產(chǎn)生的線程),觀察者線程(處理事件的線程)炸渡,訂閱關(guān)系產(chǎn)生的線程(一般都是主線程)娜亿。

一般情況下,在同步的觀察者模式中(或者我們不進(jìn)行任何線程的切換)蚌堵,事件產(chǎn)生的線程和事件處理線程還有訂閱關(guān)系發(fā)生的線程是同一個(gè)線程(這個(gè)線程就是訂閱關(guān)系產(chǎn)生的線程)买决。

RxJava的觀察者模式是一種擴(kuò)展的觀察者模式,一個(gè)被觀察者可以發(fā)送若干的事件吼畏,這些事件組成了一個(gè)事件隊(duì)列督赤。我們可以針對(duì)每一個(gè)事件或者或者整個(gè)事件隊(duì)列進(jìn)行處理,處理完之后再發(fā)送給觀察者泻蚊。

下面來(lái)介紹一下Rxjava中這三個(gè)角色對(duì)象

  • Observer或者Subscriber躲舌,這是觀察者對(duì)象,用來(lái)處理事件性雄。

    Observer處理事件有三個(gè)方法:onNext(),onCompleted(),onError没卸,onNext()用來(lái)處理普通事件羹奉,onCompleted()在事件隊(duì)列已經(jīng)發(fā)送完普通事件的時(shí)候來(lái)調(diào)用,onError()在事件隊(duì)列發(fā)生錯(cuò)誤的時(shí)候來(lái)調(diào)用

    onCompleted()onError()是互斥的约计,事件隊(duì)列正常發(fā)送完普通事件的時(shí)候诀拭,應(yīng)該調(diào)用onCompleted(),出錯(cuò)的時(shí)候應(yīng)該調(diào)用onError()

    Subscriber相比于Observer增加了兩個(gè)方法,onStat()unsubscribe()煤蚌,

    1. onStart在訂閱關(guān)系產(chǎn)生耕挨,但是還沒(méi)有發(fā)送事件的時(shí)候調(diào)用,我們可以在這里做一些初始化的工作尉桩。但是要注意筒占,onStart方法的線程是在訂閱關(guān)系產(chǎn)生的線程,也就是說(shuō)如果訂閱關(guān)系是在主線程產(chǎn)生的蜘犁,onStart就工作在主線程中翰苫,如果訂閱關(guān)系是在工作線程產(chǎn)生的,那么onStart就工作在工作線程沽瘦。

      如果我們對(duì)于初始化的線程有要求革骨,比如要求初始化必須在主線程進(jìn)行,那么我們可以使用doOnSubscribe()方法析恋,該方法也是在訂閱關(guān)系產(chǎn)生但是還沒(méi)有發(fā)送事件的時(shí)候調(diào)用,但是該方法可以指定自己要運(yùn)行在哪一個(gè)線程中盛卡。

    2. unsubscribe()該方法是Subscription接口的方法助隧,該接口是對(duì) 訂閱關(guān)系 的一個(gè)抽象,代表了一個(gè)訂閱關(guān)系滑沧,Subscriber實(shí)現(xiàn)了這個(gè)接口并村,并且在subscribe()方法中返回了這個(gè)接口,借助這個(gè)接口滓技,當(dāng)我們不在需要訂閱被觀察者的時(shí)候哩牍,可以通過(guò)該接口的unsubscribe方法解除訂閱關(guān)系,從而防止內(nèi)存泄漏令漂。

  • Observable 被觀察者對(duì)象膝昆,用來(lái)產(chǎn)生并發(fā)送事件

  • 事件對(duì)象,我們?cè)趧?chuàng)建被觀察者對(duì)象的時(shí)候叠必,要指定被觀察者能夠產(chǎn)生什么樣子的事件荚孵,也就是事件的類(lèi)型

    ?

接下來(lái)看一下如何產(chǎn)生觀察者對(duì)象和被觀察者對(duì)象

  • 觀察者對(duì)象的生成

    正常的new方法來(lái)生成觀察者對(duì)象

    Subscriber subscriber = new Subscriber(String s){  
      @Override
      public void onNext(String s){
          
      }
      
      @Override
      public void onCompleted(){
          
      }
      
      @Override
      public void onError(Throwable e){
          
      }
    }
    

    ?

這就生成了一個(gè)觀察者對(duì)象,該觀察者感興趣的事件類(lèi)型是String

  • 被觀察者對(duì)象的生成

    Rxjava提了了幾個(gè)不同的方法來(lái)方便我們生成被觀察者對(duì)象

    1. Observable.create靜態(tài)方法

      Observable observable = Observable.create(new Observable.OnSubscribe(){
        @Override
        public void call(Subscriber subscriber){
          subscriber.onNext("hello");
          subscriber.onNext("world");
          subscriber.onCompleted();
        }
      });
      

      Observable.create方法接受Observable的內(nèi)部類(lèi)Onsubscribe作為參數(shù)纬朝,并把該OnSubscriber存儲(chǔ)起來(lái)收叶,當(dāng)訂閱關(guān)系真正發(fā)生的時(shí)候,通過(guò)OnSubscriber來(lái)調(diào)用觀察者的對(duì)應(yīng)方法共苛,實(shí)現(xiàn)消息的發(fā)送判没。

      (Observable為什么不直接存儲(chǔ)Subscriber的引用蜓萄?因?yàn)檫@個(gè)時(shí)候訂閱關(guān)系還沒(méi)有真正發(fā)生,拿不到俺畏濉)

    2. Observable.just(T...)

      just靜態(tài)方法绕德,通過(guò)傳入一系列的事件對(duì)象T來(lái)生成一個(gè)Observable對(duì)象,當(dāng)訂閱關(guān)系發(fā)生的時(shí)候摊阀,就把一系列的事件對(duì)象發(fā)送到Subscriber的onNext方法中

    3. Observable.from(Iterator it)

      from靜態(tài)方法耻蛇,通過(guò)傳入一個(gè)迭代器,把迭代器中的內(nèi)容作為一系列的事件對(duì)象胞此,從而生成一個(gè)Observable對(duì)象臣咖,當(dāng)訂閱關(guān)系發(fā)生的時(shí)候,把迭代器中的內(nèi)容作為事件發(fā)送給Subscriber的onNext方法漱牵。

  • 訂閱關(guān)系的產(chǎn)生

    通過(guò)observable.subscribe(subscriber)來(lái)發(fā)生訂閱關(guān)系

那我們看一下在發(fā)生關(guān)系的時(shí)候都做了哪些事情夺蛇,引用 扔物線中的一段代碼

public Subscription subscribe(Subscribe subscribe){
    subscribe.onStart();
    onSubscribe.call(subscribe);
    return subscribe;
}

所以,還記得我們說(shuō)Subscriber實(shí)現(xiàn)了Subscription接口酣胀,以方便在將來(lái)unsubscribe嗎刁赦?

還記得前面我們說(shuō)Subscriber的onStart方法在 訂閱關(guān)系 產(chǎn)生的線程中執(zhí)行嗎?

還記得我們Observable的靜態(tài)方法create()需要傳入一個(gè)OnSubscribe對(duì)象作為參數(shù)嗎闻镶?

通過(guò)這段代碼就都清楚了甚脉。

還有什么的要說(shuō)的嗎?

就是我們每次在發(fā)生訂閱關(guān)系的時(shí)候铆农,都需要一個(gè)被觀察者和一個(gè)觀察者牺氨,而觀察者一般都要實(shí)現(xiàn)onNext ,onCompleted,onError這三個(gè)方法,我們?cè)陂_(kāi)發(fā)中一般并不是三個(gè)方法都關(guān)心墩剖,比如只關(guān)心onNext方法猴凹,RxJava給我們提供了subscribe方法的幾個(gè)重載版本,來(lái)使我們更方便的實(shí)現(xiàn)訂閱岭皂。

比如

observable.subscribe(new Action1<String>(){
  @Override
  public void call(String s){
      
  }  
});

先說(shuō)一下ActionX<T>接口郊霎,這個(gè)接口有一個(gè)方法call(),X為N爷绘,則call方法就有N個(gè)參數(shù)书劝,并且ActionX的call方法是沒(méi)有返回值的。

比如Action1<String>就說(shuō)明call方法有一個(gè)參數(shù)揉阎,該參數(shù)的類(lèi)型是String庄撮。而onNext方法也是無(wú)返回值,也是只有一個(gè)參數(shù)毙籽,所以在上面的代碼中洞斯,RxJava就會(huì)幫助我們生成一個(gè)Subscriber,并且在這個(gè)為我們生成的Subscriber的onNext方法中,調(diào)用這個(gè)Action1的call方法烙如。類(lèi)似于Python中的閉包么抗。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市亚铁,隨后出現(xiàn)的幾起案子蝇刀,更是在濱河造成了極大的恐慌,老刑警劉巖徘溢,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吞琐,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡然爆,警方通過(guò)查閱死者的電腦和手機(jī)站粟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)曾雕,“玉大人奴烙,你說(shuō)我怎么就攤上這事∑收牛” “怎么了切诀?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)搔弄。 經(jīng)常有香客問(wèn)我幅虑,道長(zhǎng),這世上最難降的妖魔是什么肯污? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任翘单,我火速辦了婚禮,結(jié)果婚禮上蹦渣,老公的妹妹穿的比我還像新娘。我一直安慰自己貌亭,他們只是感情好柬唯,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著圃庭,像睡著了一般锄奢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上剧腻,一...
    開(kāi)封第一講書(shū)人閱讀 50,096評(píng)論 1 291
  • 那天拘央,我揣著相機(jī)與錄音,去河邊找鬼书在。 笑死灰伟,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的儒旬。 我是一名探鬼主播栏账,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼帖族,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了挡爵?” 一聲冷哼從身側(cè)響起竖般,我...
    開(kāi)封第一講書(shū)人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎茶鹃,沒(méi)想到半個(gè)月后涣雕,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡闭翩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年挣郭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片男杈。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡丈屹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出伶棒,到底是詐尸還是另有隱情旺垒,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布肤无,位于F島的核電站先蒋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏宛渐。R本人自食惡果不足惜竞漾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窥翩。 院中可真熱鬧业岁,春花似錦、人聲如沸寇蚊。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)仗岸。三九已至允耿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間扒怖,已是汗流浹背较锡。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盗痒,地道東北人蚂蕴。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親掂墓。 傳聞我的和親對(duì)象是個(gè)殘疾皇子谦纱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

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