如需下載源碼,請訪問
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發送的數據。