就在前不久做了一個關於RXJava的相關教學視頻,過後整理了關於RxJava的預習資料和相關內容以及圖文和相關源碼,需要借鑑的可以和我聯繫~
承接上文:我把RXjava的源碼和這份面試都給你了,你還告訴我面不過拿不到offer?(一)
源碼和麪試大全PDF
更多完整項目下載。未完待續。源碼。圖文知識後續上傳github。
可以點擊關於我聯繫我獲取
RxJava
在RxJava
中,一個實現了Observer接口的對象可以訂閱(subscribe)一個Observable 類的實例。訂閱者(subscriber)對Observable發射(emit)的任何數據或數據序列作出響應。這種模式簡化了併發操作,因爲它不需要阻塞等待Observable發射數據,而是創建了一個處於待命狀態的觀察者哨兵,哨兵在未來某個時刻響應Observable的通知。
####Single
介紹
RxJava(以及它派生出來的RxGroovy
和RxScala
)中有一個名爲Single的Observable變種。Single類似於Observable,不同的是,它總是隻發射一個值,或者一個錯誤通知,而不是發射一系列的值。
因此,不同於Observable需要三個方法onNext, onError, onCompleted
,訂閱Single只需要兩個方法:
onSuccess
- Single發射單個的值到這個方法onError
- 如果無法發射需要的值,Single發射一個Throwable
對象到這個方法
Single只會調用這兩個方法中的一個,而且只會調用一次,調用了任何一個方法之後,訂閱關係終止
Single的操作符
Single也可以組合使用多種操作,一些操作符讓你可以混合使用Observable和Single:
Subject
Subject可以看成是一個橋樑或者代理,在某些ReactiveX
實現中(如RxJava
),它同時充當了Observer
和Observable
的角色。因爲它是一個Observer
,它可以訂閱一個或多個Observable
;又因爲它是一個Observable
,它可以轉發它收到(Observe)的數據,也可以發射新的數據。
由於一個Subject
訂閱一個Observable
,它可以觸發這個Observable
開始發射數據(如果那個Observable
是"冷"的–就是說,它等待有訂閱纔開始發射數據)。因此有這樣的效果,Subject可以把原來那個"冷"的Observable變成"熱"的。
Subject的種類
針對不同的場景一共有四種類型的Subject。他們並不是在所有的實現中全部都存在,而且一些實現使用其它的命名約定(例如,在RxScala
中Subject被稱作PublishSubject
)。
AsyncSubject
一個AsyncSubject只在原始Observable完成後,發射來自原始Observable的最後一個值。(如果原始Observable沒有發射任何值,AsyncObject
也不發射任何值)它會把這最後一個值發射給任何後續的觀察者。
然而,如果原始的Observable
因爲發生了錯誤而終止,AsyncSubject
將不會發射任何數據,只是簡單的向前傳遞這個錯誤通知
BehaviorSubject
當觀察者訂閱BehaviorSubject
時,它開始發射原始Observable最近發射的數據(如果此時還沒有收到任何數據,它會發射一個默認值),然後繼續發射其它任何來自原始Observable的數據。
然而,如果原始的Observable因爲發生了一個錯誤而終止,BehaviorSubject
將不會發射任何數據,只是簡單的向前傳遞這個錯誤通知
PublishSubject
PublishSubject
只會把在訂閱發生的時間點之後來自原始Observable的數據發射給觀察者。需要注意的是,PublishSubject
可能會一創建完成就立刻開始發射數據(除非你可以阻止它發生),因此這裏有一個風險:在Subject被創建後到有觀察者訂閱它之前這個時間段內,一個或多個數據可能會丟失。如果要確保來自原始Observable的所有數據都被分發,你需要這樣做:或者使用Create創建那個Observable以便手動給它引入"冷"Observable的行爲(當所有觀察者都已經訂閱時纔開始發射數據),或者改用ReplaySubject
。
如果原始的Observable因爲發生了一個錯誤而終止,PublishSubject
將不會發射任何數據,只是簡單的向前傳遞這個錯誤通知。
ReplaySubject
ReplaySubject
會發射所有來自原始Observable的數據給觀察者,無論它們是何時訂閱的。也有其它版本的ReplaySubject
,在重放緩存增長到一定大小的時候或過了一段時間後會丟棄舊的數據(原始Observable發射的)。
如果你把ReplaySubject
當作一個觀察者使用,注意不要從多個線程中調用它的onNext
方法(包括其它的on系列方法),這可能導致同時(非順序)調用,這會違反Observable協議,給Subject的結果增加了不確定性。
RxJava的對應類
假設你有一個Subject,你想把它傳遞給其它的代理或者暴露它的Subscriber接口,你可以調用它的asObservable
方法,這個方法返回一個Observable。具體使用方法可以參考Javadoc文檔。
串行化
如果你把 Subject 當作一個 Subscriber 使用,注意不要從多個線程中調用它的onNext方法(包括其它的on系列方法),這可能導致同時(非順序)調用,這會違反Observable協議,給Subject的結果增加了不確定性。
要避免此類問題,你可以將 Subject 轉換爲一個 SerializedSubject
,類似於這樣:
mySafeSubject = new SerializedSubject( myUnsafeSubject );
調度器 Scheduler
如果你想給Observable操作符鏈添加多線程功能,你可以指定操作符(或者特定的Observable)在特定的調度器(Scheduler)上執行。
某些ReactiveX
的Observable操作符有一些變體,它們可以接受一個Scheduler參數。這個參數指定操作符將它們的部分或全部任務放在一個特定的調度器上執行。
使用ObserveOn
和SubscribeOn
操作符,你可以讓Observable在一個特定的調度器上執行,ObserveOn
指示一個Observable在一個特定的調度器上調用觀察者的onNext
, onError
和onCompleted
方法,SubscribeOn
更進一步,它指示Observable將全部的處理過程(包括髮射數據和通知)放在特定的調度器上執行。
RxJava示例
調度器的種類
下表展示了RxJava中可用的調度器種類:
默認調度器
在RxJava中,某些Observable操作符的變體允許你設置用於操作執行的調度器,其它的則不在任何特定的調度器上執行,或者在一個指定的默認調度器上執行。下面的表格個列出了一些操作符的默認調度器:
使用調度器
除了將這些調度器傳遞給RxJava
的Observable
操作符,你也可以用它們調度你自己的任務。下面的示例展示了Scheduler.Worker
的用法:
worker = Schedulers.newThread().createWorker();
worker.schedule(new Action0() {
@Override
public void call() {
yourWork();
}
});
// some time later...
worker.unsubscribe();
遞歸調度器
要調度遞歸的方法調用,你可以使用schedule
,然後再用schedule(this)
,示例:
worker = Schedulers.newThread().createWorker();
worker.schedule(new Action0() {
@Override
public void call() {
yourWork();
// recurse until unsubscribed (schedule will do nothing if unsubscribed)
worker.schedule(this);
}
});
// some time later...
worker.unsubscribe();
檢查或設置取消訂閱狀態
Worker類的對象實現了Subscription接口,使用它的isUnsubscribed和unsubscribe方法,所以你可以在訂閱取消時停止任務,或者從正在調度的任務內部取消訂閱,示例:
Worker worker = Schedulers.newThread().createWorker();
Subscription mySubscription = worker.schedule(new Action0() {
@Override
public void call() {
while(!worker.isUnsubscribed()) {
status = yourWork();
if(QUIT == status) { worker.unsubscribe(); }
}
}
});
Worker
同時是Subscription
,因此你可以(通常也應該)調用它的unsubscribe
方法通知可以掛起任務和釋放資源了。
延時和週期調度器
你可以使用schedule(action,delayTime,timeUnit)
在指定的調度器上延時執行你的任務,下面例子中的任務將在500毫秒之後開始執行:
someScheduler.schedule(someAction, 500, TimeUnit.MILLISECONDS);
使用另一個版本的schedule,schedulePeriodically(action,initialDelay,period,timeUnit)
方法讓你可以安排一個定期執行的任務,下面例子的任務將在500毫秒之後執行,然後每250毫秒執行一次:
someScheduler.schedulePeriodically(someAction, 500, 250, TimeUnit.MILLISECONDS);
測試調度器
TestScheduler讓你可以對調度器的時鐘表現進行手動微調。這對依賴精確時間安排的任務的測試很有用處。這個調度器有三個額外的方法:
advanceTimeTo(time,unit)
向前波動調度器的時鐘到一個指定的時間點advanceTimeBy(time,unit)
將調度器的時鐘向前撥動一個指定的時間段triggerActions( )
開始執行任何計劃中的但是未啓動的任務,如果它們的計劃時間等於或者早於調度器時鐘的當前時間
(順手留下GitHub鏈接,需要獲取相關面試等內容的可以自己去找)
https://github.com/xiangjiana/Android-MS
PDF和源碼獲取
更多完整項目下載。未完待續。源碼。圖文知識後續上傳github。
可以點擊關於我聯繫我獲取