探索RxJava的生命周期
一、基本使用
我们都知道,RxJava的使用通常需要进行三个步骤:
- 创建Observable
即被观察者,使用 RxJava 需要创建一个被观察者,它会决定什么时候触发事件以及触发怎样的事件。有点类似上游发送命令,可以在这里决定异步操作模块的顺序和异步操作模块的次数。 - 创建Observser
即观察者,它可以在不同的线程中执行任务。这种模式可以极大地简化并发操作,因为它创建了一个处于待命状态的观察者哨兵,可以在未来某个时刻响应 Observable 的通知,而不需要阻塞等待。 - 使用subscribe()进行订阅
创建了 Observable 巳和 Observer 之后,我们还需要使用 subscribe() 方法将它们连接起来,这样整个上下游就能衔接起来实现链式调用。
例子:
/**
* 基本的Rxjava流
*/
private fun basicRxjava() {
// 1.创建Observable
// val observable = Observable.just(1,2,3,4,5)
val observable = Observable.create<Int> { emitter ->
try {
emitter.onNext(1)
emitter.onNext(2)
emitter.onNext(3)
// 主动抛出异常
throw Exception("Observable数据发射错误!!!")
emitter.onNext(4)
} catch (e: java.lang.Exception) {
/**
* 主动发送异常给observer
* 此时onComplete/OnNext均不会再执行了
*/
emitter.onError(e)
}
}
/**
* 2. 创建Observer对象
* Observer是一个接口,这里将其实例化就需要重写里面的方法
*/
val observer = object : Observer<Int> {
override fun onSubscribe(d: Disposable) {
println("observer-onSubscribe...订阅开始")
}
override fun onError(e: Throwable) {
println("observer-onError...错误的信息为${e.message}")
}
// 异常发生时则不执行onComplete
override fun onComplete() {
println("observer-onComplete...Observable已发射完数据,订阅结束")
}
override fun onNext(t: Int) {
println("observer-onNext...接收到的数据为$t")
}
}
// 3. 开始订阅(被观察者“订阅”观察者)
observable.subscribe(observer)
}
just() 和create() 都是用于创建Observable的操作符,区别在于:
- just() 适用于简单的场景,当你想要立即发送一个或几个已知的值给订阅者时。
- create() 提供了更高的灵活性,允许你完全自定义 Observable 的行为,包括何时发射数据、如何处理错误以及何时完成。它更适合于复杂的异步操作和自定义数据流。
上述例子的输出结果为:
observer-onSubscribe...订阅开始
observer-onNext...接收到的数据为1
observer-onNext...接收到的数据为2
observer-onNext...接收到的数据为3
observer-onError...错误的信息为Observable数据发射错误!!!
1.1 异常终止后观察者的生命周期
可能有小伙伴就会问了:在也就是说,在throw Exception("Observable数据发射错误!!!")
之后的emitter.onNext(4)
咋没有执行呢?并且Observer的onComplete()
回调也没有执行。这是因为Observable在抛出异常的情况下,会终止掉后续数据的发射,Observer也就不能正常结束,只会走到onError
的回调函数中。
综上所述,在Observable异常终止的情况下,observer的生命周期为:
onSubscribe->onNext->onError
1.2 数据完整发射完成后观察者的生命周期
这里将Observable主动抛出异常的代码注释掉,也不向Observer发射error事件。由于发射数据的形式简单,所以我们可以用just操作符来创建Observable。
val observable = Observable.just(1,2,3,4)
运行后的结果如下:
observer-onSubscribe...订阅开始
observer-onNext...接收到的数据为1
observer-onNext...接收到的数据为2
observer-onNext...接收到的数据为3
observer-onNext...接收到的数据为4
observer-onComplete...Observable已发射完数据,订阅结束
这里可以看到,Observer已经执行了onComplete的回调函数了。
综上所述,在Observable正常发射数据的情况下,observer的生命周期为:
onSubscribe->onNext->onComplete
二、Do操作符
do 操作符可以给 Observable 生命周期的各个阶段加上一系列的回调监听,当 Observable 执行到这个阶段时,这些回调就会被触发。在 RxJava 中包含了很多的 do… 操作符。
2.1 Do操作符的作用
操作符 |
|
---|---|
doOnNext | 当Observable发射一个数据项给它的观察者时,会先执行这个操作符指定的动作。这个操作不会改变数据项,也不会影响Observable的后续操作。 |
doOnError | 当Observable遇到错误并准备通过onError方法通知其观察者时,会先执行这个操作符指定的错误处理动作。注意:这个操作不会阻止onError通知的传递,也不会改变错误本身。 |
doOnComplete | 当Observable正常完成时,会执行这个操作符指定的完成操作。这个操作同样不会影响Observable的完成通知。 |
doOnSubscribe | 当观察者订阅Observable时,会先执行这个操作符指定的订阅动作。这可以用于记录订阅事件、管理资源等。 |
doOnTerminate | 当Observable正常完成或遇到错误时(即调用onComplete或onError方法时),会执行这个操作符指定的终止操作。这个操作允许你在Observable的生命周期结束时执行一些清理工作。 |
doOnDispose | 当Observable的订阅被取消(即调用Disposable的dispose方法时),会执行这个操作符指定的操作。这可以用于释放资源、取消后台任务等。 |
doFinally | 在Observable正常完成、遇到错误或者下游(downstream)取消订阅时执行一个特定的操作。且doFinally优先于doAfterTerminate的调用 |
doAfterTerminate | 在Observable正常完成或遇到错误时执行一个操作。但是,与doFinally不同的是,doAfterTerminate不会在下游取消订阅时被调用。 |
2.2 Do操作符的生命周期
这里直接看个demo
/**
* do操作符的执行顺序
*/
@SuppressLint("CheckResult")
private fun rxjavaDo() {
Observable.create<Int> { emitter ->
try {
emitter.onNext(1)
// throw Exception("Observable抛出异常!!!")
emitter.onNext(4)
} catch (e: java.lang.Exception) {
// 发射异常信息(否则Observer接收不到)
// emitter.onError(e)
}
}.doOnNext { value ->
println("Observable-doOnNext-value=$value")
}.doAfterNext { value ->
println("Observable-doAfterNext-value=$value")
}.doOnComplete {
println("Observable-doOnComplete")
}.doOnSubscribe {
println("Observable-doOnSubscribe")
}.doOnTerminate {
println("Observable-doOnTerminate")
}.doAfterTerminate {
println("Observable-doAfterTerminate")
}.doFinally {
println("Observable-doFinally")
}
// Observable 每发射一个数据就会触发这个回调,不仅包括onNext,还包括onComplete和onError
.doOnEach { stringNotification ->
println("*******doOnEach-start*******")
if (stringNotification.isOnNext) {
println("isOnNext")
} else if (stringNotification.isOnComplete) {
println("isOnComplete")
} else if (stringNotification.isOnError) {
println("isOnError")
}
println("*******doOnEach-end*******")
}
// 订阅后可以取消订阅
.doOnLifecycle({ disposable ->
println("Observable-doOnLifecycle-Consumer-是否disposed:${disposable.isDisposed}")
}, { println("Observable-doOnLifecycle-Action") })
.subscribe(object : Observer<Int> {
override fun onSubscribe(d: Disposable) {
println("observer-onSubscribe...订阅开始")
}
override fun onError(e: Throwable) {
println("observer-onError...错误的信息为${e.message}")
}
// 异常发生时则不执行onComplete
override fun onComplete() {
println("observer-onComplete...Observable已发射完数据,订阅结束")
}
override fun onNext(t: Int) {
println("observer-onNext...接收到的数据为$t")
}
})
}
运行的结果为:
Observable-doOnSubscribe
Observable-doOnLifecycle-Consumer-是否disposed:false
observer-onSubscribe...订阅开始
Observable-doOnNext-value=1
*******doOnEach-start*******
isOnNext
*******doOnEach-end*******
observer-onNext...接收到的数据为1
Observable-doAfterNext-value=1
Observable-doOnNext-value=4
*******doOnEach-start*******
isOnNext
*******doOnEach-end*******
observer-onNext...接收到的数据为4
Observable-doAfterNext-value=4
可以看到,Observable正常发射完数据后,Do操作符的生命周期为:
doOnSubscribe->doOnLifecycle->doOnNext->doOnEach->doAfterNext
而当Observable主动抛出异常后,执行的结果为:
Observable-doOnSubscribe
Observable-doOnLifecycle-Consumer-是否disposed:false
observer-onSubscribe...订阅开始
Observable-doOnNext-value=1
*******doOnEach-start*******
isOnNext
*******doOnEach-end*******
observer-onNext...接收到的数据为1
Observable-doAfterNext-value=1
Observable-doOnTerminate
*******doOnEach-start*******
isOnError
*******doOnEach-end*******
observer-onError...错误的信息为Observable抛出异常!!!
Observable-doFinally
Observable-doAfterTerminate
可以看到,Observabl异常终止后,Do操作符的生命周期为:
doOnSubscribe->doOnLifecycle->doOnNext->doOnEach(onNext事件)->doAfterNext->doOnTerminate->doOnEach(error事件)->doFinally->doAfterTerminate
三、filter过滤为false时Observable和Observer的生命周期
在做项目的时候,发现当filter为false时,Observable依旧会执行doOnTerminate等回调方法。导致结果不符合预期。所以这里我特地探究了下filter过滤为false时Observable和Observer的生命周期。
在上述demo中为Observable加上一层filter。即
.filter{ false }
得到的结果为:
- 异常数据终止的情况
Observable-doOnSubscribe
Observable-doOnLifecycle-Consumer-是否disposed:false
observer-onSubscribe...订阅开始
Observable-doOnNext-value=1
*******doOnEach-start*******
isOnNext
*******doOnEach-end*******
Observable-doAfterNext-value=1
Observable-doOnTerminate
*******doOnEach-start*******
isOnError
*******doOnEach-end*******
observer-onError...错误的信息为Observable抛出异常!!!
Observable-doFinally
Observable-doAfterTerminate
- 正常完成数据发射的情况
Observable-doOnSubscribe
Observable-doOnLifecycle-Consumer-是否disposed:false
observer-onSubscribe...订阅开始
Observable-doOnNext-value=1
*******doOnEach-start*******
isOnNext
*******doOnEach-end*******
Observable-doAfterNext-value=1
Observable-doOnNext-value=4
*******doOnEach-start*******
isOnNext
*******doOnEach-end*******
Observable-doAfterNext-value=4
由输出结果可以看到:Observable的生命周期还是正常执行的,但Observer的onNext却没有收到任何数据。这说明:filter操作符过滤为false时,它仅影响传递给Observer的数据,而不直接影响Observable或Observer的生命周期。