RxJava框架已經(jīng)出來很久,但是我卻是最近才去了解這個框架,還有很多內(nèi)容沒有搞清楚,而且我對這個框架的使用也是更多的停留在異步操作和一些響應式。但是我還是希望能和大家分享下我的學習心得。
RxJava使用的是一個觀察者模式。Observable是一個被觀察者,Observer是一個觀察者,兩者間通過subscribe()進行訂閱。
代碼表示:
Observable對象被創(chuàng)建時,會將OnSubscribe對象保存。
在觀察者Observer是一個接口Interface,它有一個抽象類Subscriber。Subscriber對Observer接口進行了一些擴展,但他們的基本使用方式是完全一致的。
Subscriber相比于Observer多了onStart()方法,這個方法是在事件發(fā)送前調(diào)用的。還有一個unSubscribe()是用來取消訂閱的。
其實在subscribe()里面就是以Subscriber進行傳遞的。而且觀察者是一個Observer對象的話,也會轉(zhuǎn)變成Subscriber對象的。
在源碼中的實現(xiàn)(不是源碼,只是類似實現(xiàn)這樣的功能的偽代碼)
大家可以看到在onSubscribe的call()是在訂閱后才進行回調(diào)的,而且OnSubscribe中call()的傳入的Subscriber就是我們所構(gòu)建的觀察者subscriber對象。而在這之前是先執(zhí)行subscriber的onStart()方法。所以我們一般可以在onStart()方法里面做一些準備工作。
create()方法是RxJava最基本的創(chuàng)造事件序列的方法。基于這個方法,RxJava還提供了一些方法來快捷創(chuàng)建事件隊列:
? ? ? just()會將傳入的對象組一次發(fā)送:如:just("1","2","3")就類似于subscriber.onNext("1");subscriber.onNext("2");subscriber("3");subscriber.onCompleted();
? ? ?from(T[])/from(Iterale)將傳入的數(shù)組或Iterable拆分成具體對象后,依次發(fā)送出來。(和上面大同小異)
其實這兩個方法最終都是會轉(zhuǎn)成create()來進行發(fā)送,而just中的參數(shù)大于1個對象時會轉(zhuǎn)變成form(T[])形式進行發(fā)送。而form(T[])的數(shù)組等于1是又會轉(zhuǎn)成just()進行發(fā)送。
在數(shù)組長度為1的時候會just方法中會轉(zhuǎn)變成create(),發(fā)送數(shù)組的過程為:
而在數(shù)組長度大于1時,同樣會轉(zhuǎn)變成create(),發(fā)送數(shù)組的過程為:
變換:
如果有這樣的邏輯,傳入一個url,然后下載圖片,再顯示在imageview中。其實就涉及都一個url轉(zhuǎn)成bitmap的過程。
在RxJava中提供了一些轉(zhuǎn)變的方法:
map()可以將OnSubscribe發(fā)送過來的事件依次轉(zhuǎn)換成自己想要的類型然后發(fā)送給subscriber對象中。
map()方法中的傳遞的參數(shù)是一個Func1<T,R>對象,T為onSubscribe中發(fā)送事件的類型,R為要轉(zhuǎn)變成的類型。在這個對象中有一個回調(diào)方法call,這個方法中的參數(shù)為onSubscribe中的發(fā)送的事件,返回值為要轉(zhuǎn)變的類型。最后這個轉(zhuǎn)變后的對象會被發(fā)送到Subscriber的onNext()中。
map()方法只能將事件一個一個的轉(zhuǎn)換,但是有這樣的情,比如況我們發(fā)送一組文件夾的對象,一個文件夾中又包含有一個圖片集合。我們要講圖片一一提取。如果用map()的話:
雖然能夠?qū)崿F(xiàn),但是總感覺不是特別方便,因為我們要在Subscriber中做遍歷。
flatMap(),RxJava中另一個變換的方法。在flatMap中的參數(shù)同樣是Func1對象,但是它的泛型結(jié)構(gòu)是這樣的Func1<T,Observable<R>>,T為OnSubscriber中發(fā)送的事件類型,而R為轉(zhuǎn)變后的類型。
其實在RxJava中的一些列的轉(zhuǎn)變,都是基于lift()的。
在lift()會返回一個新創(chuàng)建的Observable對象
大家可以看到在lift()會重新創(chuàng)建一個Observable對象返回,并且會創(chuàng)建一個OnSubscribeLift對象,OnSubscribeLift類是OnSubscribe的一個實現(xiàn)類,會作為新的Observable的onSubscribe對象保存起來。在構(gòu)造OnSubscribeLift的時候會將當前OnServable對象作為參數(shù)(即create()中的OnSubscribe),而lift()中的參數(shù)--Operator對象也會作為參數(shù)傳入。
而在OnSubscribe的Call()的源碼:
可以看到,其實在call()中回調(diào)了上一個Observable中的OnSubscribe的call方法。
因為lift會創(chuàng)建一個新的Observable并返回,所以Observale.create().lift().subscribe(Subscriber)的過程可以看成是:
所以最后的訂閱操作其實是newObservable與Subscriber對象的訂閱。
大致調(diào)用流程為:
線程控制
在不指定線程的情況下,以上的所有操作都默認是在同一線程進行的。就是在哪個線程進行訂閱操作的話就默認在這個線程執(zhí)行所有的發(fā)送事件和消費事件。
但是RxJava最重要的就是異步操作,是如何實現(xiàn)的呢,就需要用到Scheduler -- 調(diào)度器。
在RxJava中內(nèi)置了幾個Scheduler:
我們可以使用subscribeOn()和ObserveOn()兩個方法來進行線程控制。
subscriberOn()指定的是事件生產(chǎn)線程:即為OnSubscribe中的call()運行的線程。
observeOn()指定的是事件消費線程:即為Subscriber所運行的線程。
這次分享就先跟大家分享到這里,如果有哪些錯誤的地方也希望大家能指出來。因為線程控制的一些原理還不是特別懂,也不敢跟大家瞎分享,所以就寫了這么一點。如果大家想了解多一點的話,大家可以看下扔物線的一篇博客《給 Android 開發(fā)者的 RxJava 詳解》http://gank.io/post/560e15be2dca930e00da1083,個人感覺寫得非常好,我的很多分享都是從那里看來的。還有大家在學習的時候可以結(jié)合源代碼,這樣對原理的理解會更加深刻,同時也方便大家理解。
謝謝!!!!