把它當(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
, ResourceSubscriber
和 DisposableSubscriber
等抽象類。
-
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)
由于Observer
和Subscriber
都是接口俺抽,方法又都只有四個(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毁兆。
我們?nèi)ヒ粋€(gè)一個(gè)的看這幾個(gè)類的subscribe方法浙滤,我們會(huì)發(fā)現(xiàn)
Completable
對(duì)應(yīng)的傳參是onComplete的action
,Single
對(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è)類里看一下
- Disposable
/**
-
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();
}
- Dispose the resource, the operation should be idempotent.
是個(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)