RxJava 基礎知識
RxJava建立操作符
注: 使用Rxjava之前需要新增依賴
dependencies {
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'io.reactivex.rxjava2:rxjava:2.2.0'
implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0'
// 注:RxJava2 與 RxJava1 不能共存,即依賴不能同時存在
}
複製程式碼
操作符 | 作用 |
---|---|
create() | 使用一個函式從頭建立一個Observable |
just() | 將一個或多個物件轉換成發射這個或這些物件的一個Observable |
from() | 將一個Iterable,一個Future或者一個陣列轉換成一個Observable |
defer() | 只有當訂閱者訂閱才建立Observable,為每個訂閱建立一個新的Observable |
range() | 建立一個發射指定範圍的整數序列的Observable |
interval() | 建立一個按照給定的時間間隔發射整數序列的Observable |
timer() | 建立一個在給定的延遲之後發射單個資料的Observable |
empty() | 建立一個什麼都不做直接通知完成的Observable |
error() | 建立一個什麼都不做直接通知錯誤的Observable |
never() | 建立一個不發射任何資料的Observable |
一. Create
使用一個函式從頭開始建立一個Observable
RxJava建議我們在傳遞create方法的函式時,先檢查一下觀察者的isDisposed狀態,以便在沒有觀察者的時候,讓我們的Observable停止發射資料,防止執行昂貴的運算
- 實際應用
fun testCreate() {
Observable.create<Int> {
//判斷Observable的isDisposed狀態
if (!it.isDisposed) {
it.onNext(1)
it.onNext(2)
it.onNext(3)
it.onComplete()
}
}.subscribeBy(
onNext = { Log.e("TAG", "onNext: ${it.toString()}") },
onComplete = { Log.e("TAG", "onComplete") }
)
}
複製程式碼
執行結果
onNext: 1
onNext: 2
onNext: 3
onComplete
複製程式碼
二. Just
建立一個發射指定值的Observable
just 可以接受一至十個引數,返回一個按引數列表順序發射這些資料的Observable
- 實際應用
fun testJust(){
Observable.just(1,2,3,4,5,6,7,8,9,10)
.subscribeBy(
onNext = { Log.e("TAG", "onNext: ${it.toString()}") },
onComplete = { Log.e("TAG", "onComplete") }
)
}
複製程式碼
執行結果
onNext: 1
onNext: 2
onNext: 3
onNext: 4
onNext: 5
onNext: 6
onNext: 7
onNext: 8
onNext: 9
onNext: 10
onComplete
複製程式碼
如果在just()中傳入null,則會丟擲一個空指標異常
三. From
將其他種類的物件和資料型別轉換為Observable
- 實際應用
fun testFrom(){
val list = arrayListOf<Int>(1,2,3,4,5)
list.toObservable()
.subscribeBy(
onNext = { Log.e("TAG", "onNext: ${it.toString()}") },
onComplete = { Log.e("TAG", "onComplete") }
)
}
複製程式碼
執行結果
onNext: 1
onNext: 2
onNext: 3
onNext: 4
onNext: 5
onComplete
複製程式碼
對於Future,它會發射Future.get()方法返回的單個資料
class MyCallable : Callable<String>{
override fun call(): String {
Log.e("TAG","模擬一些耗時操作...")
Thread.sleep(5000)
return "OK"
}
}
fun testFromFuture(){
val executorService = Executors.newSingleThreadExecutor();
val future = executorService.submit(MyCallable())
Observable.fromFuture(future)
.subscribeBy(
onNext = {Log.e("TAG","onNext: $it")}
)
}
複製程式碼
執行結果
模擬一些耗時操作...
onNext: OK
複製程式碼
from方法有一個可接受兩個可選引數的版本,分別指定超時時長和時間單位.如果過了指定的時長,Future還沒有返回,Observable就會發射錯誤通知並終止
fun testFromFuture(){
val executorService = Executors.newSingleThreadExecutor();
val future = executorService.submit(MyCallable())
Observable.fromFuture(future,3,TimeUnit.SECONDS)
.subscribeBy(
onNext = {Log.e("TAG","onNext: $it")}
)
}
複製程式碼
執行結果
模擬一些耗時操作...
AndroidRuntime: FATAL EXCEPTION: main
io.reactivex.exceptions.OnErrorNotImplementedException
複製程式碼
四. Repeat
建立一個發射特定資料重複多次的Observable
repeat 不是建立一個Observable,而是重複發射原始Observable的資料序列,這個序列可以是無限的,也可以通過repeat(n)指定重複次數
fun testRepeat(){
Observable.just("hello")
//.repeat() //無限
.repeat(3) //迴圈3次
.subscribeBy(
onNext = { Log.e("TAG", "onNext: ${it.toString()}") },
onComplete = { Log.e("TAG", "onComplete") },
onError = { it.printStackTrace() }
)
}
複製程式碼
執行結果
onNext: hello
hello
onComplete
複製程式碼
在RxJava2.x中還有兩個repeat相關的操作符: repeatWhen 和 repeatUntil
1. repeatWhen
repeatWhen 不是快取和重複原始Observable的資料序列,而是根據指定的條件重新訂閱和釋出原來的Observable
fun testRepeatWhen(){
Observable.range(0,5)
.repeatWhen {
Observable.timer(10,TimeUnit.SECONDS)
}
.subscribeBy(
onNext = { Log.e("TAG", "onNext: ${it.toString()}") },
onComplete = { Log.e("TAG", "onComplete") },
onError = { it.printStackTrace() }
)
}
複製程式碼
執行結果
09-06 05:55:14.901 22472-22472/com.mufeng.rxjavademo E/TAG: onNext: 0
onNext: 1
onNext: 2
onNext: 3
onNext: 4
09-06 05:55:24.903 22472-22505/com.mufeng.rxjavademo E/TAG: onNext: 0
09-06 05:55:24.904 22472-22505/com.mufeng.rxjavademo E/TAG: onNext: 1
onNext: 2
onNext: 3
onNext: 4
09-06 05:55:24.911 22472-22505/com.mufeng.rxjavademo E/TAG: onComplete
複製程式碼
2. repeatUntil
repeatUntil是RxJava2.x新增的操作符,表示直到某個條件就不在重複發射資料
fun testRepeatUntil(){
val time = System.currentTimeMillis();
Observable.just("hello")
.repeatUntil {
System.currentTimeMillis() - time > 5000
}
.subscribeBy(
onNext = { Log.e("TAG", "onNext: ${it.toString()}") },
onComplete = { Log.e("TAG", "onComplete") },
onError = { it.printStackTrace() }
)
}
複製程式碼
執行結果
09-06 06:02:15.220 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:16.552 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:16.552 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:16.568 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:16.569 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:16.578 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:16.579 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:16.579 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:16.579 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:16.580 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:16.580 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:16.581 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:16.581 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:16.583 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:16.584 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:16.609 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:16.609 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:18.384 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:18.384 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:20.177 22728-22728/com.mufeng.rxjavademo E/TAG: onNext: hello
09-06 06:02:20.178 22728-22728/com.mufeng.rxjavademo E/TAG: onComplete
複製程式碼
五. Empty/Never/Error
1. empty()
建立一個觀察者物件,只傳送onComplete事件
Observable.empty<Int>()
.subscribeBy(
onNext = { Log.e("TAG","接受onNext事件==$it")},
onError = { Log.e("TAG","響應Error事件: ${it.localizedMessage}")},
onComplete = { Log.e("TAG","響應Complete事件")}
)
複製程式碼
2. error()
該方法建立的被觀察者物件傳送事件的特點:僅傳送Error事件,直接通知異常
可自定義異常
Observable.error<Int>(Throwable("未知異常"))
.subscribeBy(onError = { Log.e("TAG","響應Error事件: ${it.localizedMessage}")})
複製程式碼
3. never()
不傳送任何事件
Observable.never<Int>()
.subscribeBy(
onNext = { Log.e("TAG","接受onNext事件==$it")},
onError = { Log.e("TAG","響應Error事件: ${it.localizedMessage}")},
onComplete = { Log.e("TAG","響應Complete事件")}
)
複製程式碼
六. Defer
直到有觀察者訂閱時,才動態建立Observable 併為每個觀察者建立一個全新的Observable
每次訂閱時, 都會得到一個剛建立的最新的Observable物件, 可以確保Observable物件裡面的資料是最新的
- 常用操作符
- RxJava 2․x: defer
- RxKotlin: defer
//第一次賦值
var i = 100
val observable = Observable.defer {
Observable.just(i)
}
//第二次複製
i = 200
//進行訂閱, 此時才會去用defer()操作符去建立Observable物件
observable.subscribeBy(
onNext = { Log.e("TAG", "接受onNext事件==$it") },
onError = { Log.e("TAG", "響應Error事件: ${it.localizedMessage}") },
onComplete = { Log.e("TAG", "響應Complete事件") }
)
複製程式碼
七. Timer
建立一個Observable, 它在一個給定的延遲後發射一個特殊的值
Observable.timer(2, TimeUnit.SECONDS)
.subscribeBy(
onNext = { Log.e("TAG", "接受onNext事件==$it") },
onError = { Log.e("TAG", "響應Error事件: ${it.localizedMessage}") },
onComplete = { Log.e("TAG", "響應Complete事件") }
)
複製程式碼
八. Interval
按照一個固定時間間隔發射整數序列的Observable
- 常用操作符
- RxJava 2.X: interval
- RxKotlin: interval
/**
* 第一個引數: 第一次延遲時間
* 第二個引數: 後續傳送事件的間隔時間
* 第三個引數: 時間單位
*/
Observable.interval(2,1,TimeUnit.SECONDS)
.subscribeBy(
onNext = { Log.e("TAG", "接受onNext事件==$it") },
onError = { Log.e("TAG", "響應Error事件: ${it.localizedMessage}") },
onComplete = { Log.e("TAG", "響應Complete事件") }
)
複製程式碼
九. Range
連續傳送一個事件序列,可以指定範圍
/**
* range 傳送整數序列,沒有延遲
* 第一個引數: 事件序列的起始點
* 第二個引數: 事件數量
* 如果設定成負數則會直接丟擲異常
*/
Observable.range(3,10)
.subscribeBy(
onNext = { Log.e("TAG", "接受onNext事件==$it") },
onError = { Log.e("TAG", "響應Error事件: ${it.localizedMessage}") },
onComplete = { Log.e("TAG", "響應Complete事件") }
)
/**
* intervalRange: 傳送整數序列,可以設定延遲
* 第一個引數: 事件序列起始點
* 第二個引數: 事件數量
* 第三個引數: 事件時間間隔
* 第四個引數: 事件單位
*/
Observable.intervalRange(3,10,2,1,TimeUnit.SECONDS)
.subscribeBy(
onNext = { Log.e("TAG", "接受onNext事件==$it") },
onError = { Log.e("TAG", "響應Error事件: ${it.localizedMessage}") },
onComplete = { Log.e("TAG", "響應Complete事件") }
)
複製程式碼
以上是Observable建立操作符的使用,這些操作符不僅在Observable可以使用,在Flowable等也可以使用
Demo地址: RxJavaDemo