Rxjava2入門教程二:Observable與Observer響應式編程在Rxjava2中的典型實現(轉)

如需下載源碼,請訪問

https://github.com/fengchuanfang/Rxjava2Tutorial

文章原創,轉載請注明出處:

Rxjava2入門教程二:Observable與Observer響應式編程在Rxjava2中的典型實現

在RxJava中,函數響應式編程具體表現為一個觀察者(Observer)訂閱一個可觀察對象(Observable),通過創建可觀察對象發射數據流,經過一系列操作符(Operators)加工處理和線程調度器(Scheduler)在不同線程間的轉發,最后由觀察者接受并做出響應的一個過程

ObservableSource與Observer是RxJava2中最典型的一組觀察者與可觀察對象的組合,其他四組可以看做是這一組的改進版或者簡化版。

Observable

抽象類Observable是接口ObservableSource下的一個抽象實現,我們可以通過Observable創建一個可觀察對象發射數據流。

demo1_1.jpg

上例中,調用Observable.create創建一個可觀察對象,并發送“Hello World”,然后通知發送完成

Observer

創建一個觀察者Observer來接受并響應可觀察對象發射的數據流

demo1_2.jpg

在onNext方法中接收到可觀察對象發射的數據"Hello World",并做出響應——打印到控制臺。

Observer訂閱Observable

demo1_3.jpg

一旦Observer與Observable建立了訂閱關系,Observer與Observable便成為了一個整體,Observer便可對Observable中的行為作出響應。

Emitter/Observer

通過Observable.create創建可觀察對象時,我們可以發現具體執行發射動作的是接口ObservableEmitter的實例化對象,而ObservableEmitter 繼承自 接口Emitter,查看源碼接口Emitter的具體代碼如下:

publicinterfaceEmitter{//用來發送數據,可多次調用,每調用一次發送一條數據voidonNext(@NonNull T value);//用來發送異常通知,只發送一次,若多次調用只發送第一條voidonError(@NonNull Throwable error);//用來發送完成通知,只發送一次,若多次調用只發送第一條voidonComplete();}

onNext:用來發送數據,可多次調用,每調用一次發送一條數據

onError:用來發送異常通知,只發送一次,若多次調用只發送第一條

onComplete:用來發送完成通知,只發送一次,若多次調用只發送第一條

onError與onComplete互斥,兩個方法只能調用一個不能同時調用,數據在發送時,出現異常可以調用onError發送異常通知也可以不調用,因為其所在的方法subscribe會拋出異常,若數據在全部發送完之后均正常可以調用onComplete發送完成通知;其中,onError與onComplete不做強制性調用。

接口Observer中的三個方法(onNext,onError,onComplete)正好與Emitter中的三個方法相對應,分別對Emitter中對應方法的行為作出響應。

Emitter調用onNext發送數據時,Observer會通過onNext接收數據。

Emitter調用onError發送異常通知時,Observer會通過onError接收異常通知。

Emitter調用onComplete發送完成通知時,Observer會通過onComplete接收完成通知。

步驟簡化

去掉中間變量可以對之前的代碼簡化為以下形式:

demo2.jpg

在響應式編程的基礎上,加上函數式編程,真正的函數響應式編程可以將代碼簡化成以下形式:

demo3.jpg

其中,just操作符是經過封裝后,專門用來發射單條數據的,可以是一個數據,一條字符,一個對象,一整個數組,一整個集合。

Consumer可以看做是對觀察者Observer功能單一化之后的產物——消費者,上例中的Consumer通過其函數accept只接收可觀察對象發射的數據,不接收異常信息或完成信息。

如果想接收異常信息或完成信息可以用下面的代碼:

demo4.jpg

第二個參數Consumer規定泛型通過函數accept接收異常信息。

第三個參數Action也是對觀察者Observer功能單一化之后的產物--行動,通過函數run接收完成信息,作出響應行動。

發送數據序列

Observable可以發送單條數據或者數據序列,上面的事例都是發送單條數據'Hello World"的情形,那么怎樣發送數據序列呢?

可以通過最基礎的方法:

demo5.jpg

通過在方法subscribe中循環遍歷String類型的集合list中的元素,然后通過emitter.onNext(str)將他們逐一發送;如果發送過程中捕獲到異常,通過emitter.onError(e)發送異常信息;最后如果數據正常發送完畢調用 emitter.onComplete()發送完成通知,Observer中通過onNext接收emitter發送的每一條信息并打印到控制臺(emitter發送幾次,Observer便接收幾次),通過onError(Throwable e)接收異常信息,onComplete()接收完成信息。

同樣可以通過操作符對其進行簡化,如下;

demo6.jpg

其中fromIterable(list)也是一個封裝好的操作符,可以將一個可迭代對象中的每一個元素逐一發送

Disposable

在之前的例子中,可以看到Observer接口中還有一個方法沒有說

publicvoidonSubscribe(Disposable d){}

這個方法中有個Disposable類型的參數,

onSubscribe表示在訂閱時,當觀察者Observer訂閱可觀察對象Observable,建立訂閱關系后,會觸發這個方法,并且會生成一個Disposable對象,其實無論觀察者Observer以何種方式訂閱可觀察對象Observable,都會生成一個Disposable,不管有沒有onSubscribe(Disposable d)方法,如下:

demo7.jpg

查看Disposable接口的源碼,如下:

publicinterfaceDisposable{voiddispose();booleanisDisposed();}

Disposable是觀察者Observer與可觀察對象Observable建立訂閱關系后生成的用來取消訂閱關系和判斷訂閱關系是否存在的一個接口。

只有當觀察者Observer與可觀察對象Observable之間存在訂閱關系時,Observer才能接收Observable發送的數據或信息。如果Observer在接收Observable的信息的過程中,取消了訂閱關系,則Observer只能接收訂閱關系取消之前Observable發送的數據,對于訂閱關系取消之后Observable發送的數據,Observer將不會再接收。

運行下面的代碼,當Observable接收到第5條數據時,取消訂閱關系。

demo8.jpg

控制臺日志如下:

I/System.out: 發送0

I/System.out: 接收0

I/System.out: 發送1

I/System.out: 接收1

I/System.out: 發送2

I/System.out: 接收2

I/System.out: 發送3

I/System.out: 接收3

I/System.out: 發送4

I/System.out: 接收4

I/System.out: 發送5

I/System.out: 接收5

I/System.out: 發送6

I/System.out: 發送7

I/System.out: 發送8

I/System.out: 發送9

可以發現取消訂閱關系之前,Observable發送一條數據,Observe接收一條,取消訂閱關系之后,Observe將不再接收Observable發送的數據。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,637評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,555評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,629評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,976評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,139評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,686評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,411評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,641評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,820評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,362評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,604評論 2 380

推薦閱讀更多精彩內容