RxJava2.X 學習筆記 -- 建立操作符

小碼農沐楓發表於2018-09-04

RxJava 基礎知識

image

RxJava建立操作符

image

注: 使用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

image

官方文件: reactivex.io/documentati…

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

image

官方文件: reactivex.io/documentati…

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

image

  • 實際應用
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

image

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事件

image

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事件,直接通知異常
可自定義異常

image

Observable.error<Int>(Throwable("未知異常"))
        .subscribeBy(onError = { Log.e("TAG","響應Error事件: ${it.localizedMessage}")})
複製程式碼

3. never()

不傳送任何事件

image

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物件裡面的資料是最新的

image

  • 常用操作符
  1. RxJava 2․x: defer
  2. 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, 它在一個給定的延遲後發射一個特殊的值

image

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

image

  • 常用操作符
  1. RxJava 2.X: interval
  2. 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

連續傳送一個事件序列,可以指定範圍

image

/**
 * 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


相關文章