優(yōu)勢 - 邏輯簡潔
Rx 優(yōu)勢可以概括為四個字禁筏,那就是 邏輯簡潔浅碾。然而,邏輯簡潔并不意味著代碼簡潔翘单。
由于鏈式結構,一條龍揪阶,你可以從頭到尾,從上到下,很清楚的看到這個連式結構的執(zhí)行順序诗赌。
對于開發(fā)人員來說,代碼質量并不在于代碼量秸弛,而在于邏輯是否清晰簡潔铭若,可維護性如何,代碼是否健壯递览!
需要了解的概念
Observable(被觀察者)
Observer/Subscriber(觀察者)
</br>
Observable 發(fā)出一系列事件他是事件的產(chǎn)生者叼屠;
Subscriber 負責處理事件,他是事件的消費者绞铃;
Operator 是對 Observable 發(fā)出的事件進行修改和變換镜雨;
AndroidStudio中使用Rx需要的環(huán)境
在app的build.gradle加入以下引用包
/*Rx引入包*/
compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.5'
/*漂亮Log*/
compile 'com.github.orhanobut:logger:1.12'
如果你想使用漂亮的Logger打印
在項目的build.gradle加入以下
allprojects {
repositories {
jcenter()
/*漂亮Log*/
maven { url "https://jitpack.io" }
}
}
下面的我就不上代碼直接上圖了,最好跟著圖一起動手敲一敲儿捧,最后我會上代碼地址
創(chuàng)建Observable(被觀察者) 的兩種方法
Paste_Image.png
創(chuàng)建Observer/Subscriber(觀察者) 的方法
Paste_Image.png
最后荚坞,我們可以調用 subscribe 操作符, 進行事件訂閱菲盾。
Paste_Image.png
代碼是都實現(xiàn)了颓影,大致的理解下他們的意思
1 Observer 是觀察者 - *** Subscriber 也是觀察者Subscriber 是一個實現(xiàn)了Observer接口的抽象類***,對 Observer 進行了部分擴展懒鉴,在用上基本沒有區(qū)別诡挂;Subscriber 多了發(fā)送之前調用的 onStart() 和解除訂閱關系的 unsubscribe()方法。
2 并且疗我,在 RxJava 的 subscribe 過程中咆畏,Observer 也總是會先被轉換成一個 Subscriber 再使用。所以在這之后的示例代碼吴裤,都使用 Subscriber 來作為觀察者旧找。
在 Subscriber 實現(xiàn)的三個方法中,顧名思義麦牺,對應三種不同狀態(tài):
1 onComplete() 事件全部處理完成后回調
2 onError(Throwable t)事件處理異撑ブ耄回調
3 onNext(T t) 每接收到一個事件,回調一次
對于事件消費與事件訂閱來說剖膳,好像為了打印一個“Hello World魏颓!”要費好大的勁… 其實,RxJava 自身提供了精簡回調方式吱晒,我們可以為 Subscriber 中的三種狀態(tài)根據(jù)自身需要分別創(chuàng)建一個回調動作 Action
Paste_Image.png
那么甸饱,RxJava 的事件訂閱支持以下三種不完整定義的回調。
1 observable.subscribe(onNextAction);
2 observable.subscribe(onNextAction, onErrorAction);
3 observable.subscribe(onNextAction, onErrorAction, onCompleteAction);
我們可以根據(jù)當前需要,傳入對應的 Action叹话, RxJava 會相應的自動創(chuàng)建 Subscriber
1 Action0 表示一個無回調參數(shù)的Action偷遗;
2 Action1 表示一個含有一個回調參數(shù)的Action;
3 當然驼壶,還有Action2 ~ Action9氏豌,分別對應2~9個參數(shù)的Action;
4 每個Action热凹,都有一個 call() 方法泵喘,通過泛型T,來指定對應參數(shù)的類型般妙;
前面講解了事件的產(chǎn)生到消費纪铺、訂閱的過程,下面就舉個完整的例子碟渺。
通過Rx寫個小例子就是顯示一張圖片
從res/mipmap中取出一張圖片霹陡,顯示在ImageView上。
上面示例是RxJava最基本的一個用法止状。稍微消化一下,繼續(xù)~~
RxJava 進階 Scheduler線程控制
默認情況下攒霹,RxJava事件產(chǎn)生和消費均在同一個線程中怯疤,例如在主線程中調用,那么事件的產(chǎn)生和消費都在主線程催束。
所以集峦,RxJava 的第一個牛逼之處在于可以自由切換線程!那么抠刺,如何做塔淤?
在 RxJava 中,提供了一個名為 Scheduler的線程調度器速妖,RxJava 內部提供了4個調度器高蜂,分別是:Schedulers.io(): I/O 操作(讀寫文件、數(shù)據(jù)庫罕容、網(wǎng)絡請求等)备恤,與newThread()差不多,區(qū)別在于io() 的內部實現(xiàn)是是用一個無數(shù)量上限的線程池锦秒,可以重用空閑的線程露泊,因此多數(shù)情況下 io()效率比 newThread() 更高。值得注意的是旅择,在 io()下惭笑,不要進行大量的計算,以免產(chǎn)生不必要的線程;
1 Schedulers.newThread(): 開啟新線程操作沉噩;
2 Schedulers.immediate(): 默認指定的線程捺宗,也就是當前線程;
3 Schedulers.computation():計算所使用的調度器屁擅。這個計算指的是 CPU 密集型計算偿凭,即不會被 I/O等操作限制性能的操作,例如圖形的計算派歌。這個 Scheduler 使用的固定的線程池弯囊,大小為 CPU 核數(shù)。值得注意的是胶果,不要把 I/O 操作放在computation() 中匾嘱,否則 I/O 操作的等待時間會浪費 CPU;
4 AndroidSchedulers.mainThread(): RxJava 擴展的 Android 主線程早抠;
我們可以通過 subscribeOn() 和 observeOn() 這兩個方法來進行線程調度,依然還是顯示一張圖片霎烙,不同的是,這次是從網(wǎng)絡上加載圖片
所以蕊连,這段代碼就做一件事悬垃,在 io 線程加載一張網(wǎng)絡圖片,加載完畢之后在主線程中顯示到ImageView上甘苍。
RxJava的又一牛逼之處尝蠕,在于 變換,稍微消化一下,繼續(xù)~~
變換载庭,啥意思呢看彼? 就是將發(fā)送的事件或事件序列,加工后轉換成不同的事件或事件序列囚聚。
Observable 創(chuàng)建了一個 String 事件靖榕,也就是產(chǎn)生一個url,通過 map 操作符進行變換顽铸,返回Drawable對象茁计。
邏輯表示就是:**Observable<String> --> map變換 --> Observable<Drawable>**
那么,F(xiàn)unc1 是什么呢跋破?與 Action1類似,不同的是 FuncX有返回值簸淀,而 ActionX沒有。為什么需要返回值呢毒返?目的就在于對象的變換租幕,由String對象轉換為Drawable對象。同樣拧簸,也有Func0 ~ Func9劲绪,對應不同的參數(shù)個數(shù)。
flatMap操作符
不難發(fā)現(xiàn),上述的 map 操作符贾富,是一對一的變換歉眷,并且返回的是變換后的對象。而flatMap操作符可以適應一對多颤枪,并且返回的是一個 Observable
汗捡。應用場景舉例:例如一個員工負責多個任務,現(xiàn)在要打印所有員工的所有任務畏纲。
執(zhí)行結果為順序打印出兩位員工的所有任務列表
通過上面的代碼可以看出扇住,map 與 flatMap 這兩個操作符的共同點在于,他們都是把一個對象轉換為另一個對象盗胀,但須注意以下這些特點:
1 flatMap返回的是一個Observable對象艘蹋,
2 map 返回的是一個普通轉換后的對象;
3 flatMap返回的Observable對象并不是直接發(fā)送到Subscriber的回調中,而是重新創(chuàng)建一個Observable對象票灰,并激活這個Observable對象女阀,使之開始發(fā)送事件
4 map變換后返回的對象直接發(fā)到Subscriber回調中;
5 flatMap 變換后產(chǎn)生的每一個Observable對象發(fā)送的事件屑迂,最后都匯入同一個Observable浸策,進而發(fā)送給Subscriber回調;
6 map返回類型 與 flatMap返回的Observable事件類型惹盼,可以與原來的事件類型一樣的榛;可以對一個Observable多次使用 map和 flatMap