一篇就够系列:RxJava 核心解密

一篇就够系列:RxJava 核心解密

前言

很高兴遇见你~

众所周知,RxJava 是一个非常流行的第三方开源库,它能将复杂的逻辑简单化,提高我们的开发效率,一个这么好用的库,来让我们来学习一下吧🍺

下面我抛出一些问题,如果你都知道,那么恭喜你,你对 RxJava 掌握的很透彻,如果你对下面这些问题有一些疑惑,那么你就可以接着往下看,我会由浅入深的给你讲解 RxJava,看完之后,这些问题你会非常明了

1、什么是观察者模式?什么是装饰者模式?

2、观察者模式,装饰者模式在 RxJava 中的应用?

3、RxJava map 和 flatMap 操作符有啥区别?

4、如果有多个 subscribeOn ,会是一种什么情况?为啥?

5、如果有多个 observeOn ,会是一种什么情况?为啥?

6、RxJava 框架流思想设计?

7、RxJava 的 Subject 是什么?

8、如何通过 RxJava 实现一个自己的事件总线?

一、设计模式介绍

我们先了解一下下面两种设计模式:

1、观察者模式

2、装饰者模式

1.1、观察者模式

1.1.1、观察者模式定义

简单的理解:对象间存在一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新

1.1.2、观察者模式示例

//1、定义一个观察者的接口
interface Observer {
    /**
     * 接收事件的方法
     */

    fun onChange(o: Any)
}

//2、定义一个被观察者的接口
interface Observable {
    /**
     * 添加观察者
     */

    fun addObserver(observer: Observer)
    /**
     * 移除观察者
     */

    fun removeObserver(observer: Observer)
    /**
     * 发送事件通知
     */

    fun changeEvent(o: Any)
}

//3、定义一个观察者的实现类
class ObserverImplObserver {
    override fun onChange(o: Any) {
       //对事件进行打印
        println(o)
    }
}

//4、定义一个被观察者的实现类
class ObservableImplObservable {

    //存放观察者的集合
    private val observerList: MutableList<Observer> = LinkedList()

    override fun addObserver(observer: Observer) {
        observerList.add(observer)
    }

    override fun removeObserver(observer: Observer) {
        observerList.remove(observer)
    }

    override fun changeEvent(o: Any) {
        for (observer in observerList) {
            observer.onChange(o)
        }
    }
}

//5、测试
fun main(){
    //1、创建被观察者
    val observable = ObservableImpl()
    //2、创建观察者
    val observer1 = ObserverImpl()
    val observer2 = ObserverImpl()
    val observer3 = ObserverImpl()
    //3、添加观察者
    observable.addObserver(observer1)
    observable.addObserver(observer2)
    observable.addObserver(observer3)
    //4、发送事件
    observable.changeEvent("erdai666")
}
//打印结果
erdai666
erdai666
erdai666

1.2、装饰者模式

1.2.1、装饰者模式定义

简单的理解:动态的给一个类进行功能增强

1.2.2、装饰者模式示例

举个例子:我想吃个蛋炒饭,但是单独一个蛋炒饭我觉得不好吃,我想在上面加火腿,加牛肉。我们使用装饰者模式来实现它

//1、定义一个炒饭的接口
interface Rice {
    fun cook()
}

//2、定义一个炒饭接口的实现类:蛋炒饭
class EggFriedRiceRice {

    override fun cook() {
        println("蛋炒饭")
    }
}

//3、定义一个炒饭的抽象装饰类
abstract class RiceDecorate(var rice: Rice): Rice

//4、往蛋炒饭中加火腿
class HamFriedRiceDecorate(rice: Rice): RiceDecorate(rice) {
    override fun cook() {
        rice.cook()
        println("加火腿")
    }
}

//5、往蛋炒饭中加牛肉
class BeefFriedRiceDecorate(rice: Rice): RiceDecorate(rice) {

    override fun cook() {
        rice.cook()
        println("加牛肉")
    }
}

//6、测试
fun main(){
    //蛋炒饭
    val rice = EggFriedRice()
    //加火腿
    val hamFriedRiceDecorate = HamFriedRiceDecorate(rice)
    //加牛肉
    val beefFriedRiceDecorate = BeefFriedRiceDecorate(hamFriedRiceDecorate)
    beefFriedRiceDecorate.cook()
}
//打印结果
蛋炒饭
加火腿
加牛肉

装饰者模式的核心:定义一个抽象的装饰类继承顶级接口,然后持有这个顶级接口的引用,接下来就可以进行无限套娃了😄

二、手撸 RxJava 核心源码实现

ok,了解了两种设计模式,接下来我们正式进入 RxJava 的学习

2.1、RxJava 介绍

RxJava 是一个异步操作框架,其核心可以归纳为两点:1、异步事件流 2、响应式编程。接下来我们可以好好的去感受这两点

2.2、RxJava 操作符

RxJava 之所以强大源于它各种强大的操作符,掌握好这些操作符能让你对 RxJava 的使用得心应手,RxJava 操作符主要分为 6 大类:

一篇就够系列:RxJava 核心解密


每一个操作符背后都对应了一个具体的实现类,接下来我们就挑几个最常用,最核心的操作符:create,map,flatMap,observeOn,subscribeOn 进行手撸实现,相信看完这些操作符的实现后,你能融会贯通,举一反三

注意:下面这些操作符的实现和 RxJava 实现细节不尽相同,但核心思想是一致的,大家只要理解核心思想就好

2.3、create 操作符实现

create 是来创建一个被观察者对象,看了 RxJava create 操作符源码你会发现:

1、create 是使用观察者模式实现的,但 RxJava 里面使用的观察者模式和我们上面介绍的还有点不一样,它是一种变种的观察者模式

2、上面例子中我们是通过被观察者去发送事件,而 RxJava 里面定义了专门发送事件的接口,这样做的好处就是让被观察者和发射事件进行解耦

//1、定义一个观察者的顶级接口
interface Observer<T{
    //建立了订阅关系
    fun onSubscribe()
    //接收到正常事件
    fun onNext(t: T)
    //接收到 error 事件
    fun onError(e: Throwable)
    //接收到 onComplete 事件
    fun onComplete()
}

//2、定义一个被观察者的顶级接口
interface ObservableSource<T{
    //订阅观察者
    fun subscribe(observer: Observer<T>)
}

//3、定义一个被观察者抽象类实现顶层被观察者接口
abstract class Observable<T>: ObservableSource<T{

    override fun subscribe(observer: Observer<T>) {
        subscribeActual(observer)
    }
  
    //实际订阅观察者的抽象方法,让子类去实现
    protected abstract fun subscribeActual(observer: Observer<T>)

    //伴生类里面的方法,直接通过类名调用    
    companion object{
       //这里是我们实现 create 操作符对外提供和 RxJava 类似的方法调用
        fun <T> create(source: ObservableOnSubscribe<T>): ObservableCreate<T>{
            return ObservableCreate(source)
        }
    }
}

//4、定义一个与被观察者发射事件解耦的接口
interface ObservableOnSubscribe<T{
    //通过 Emitter 发射事件
    fun subscribe(emitter: Emitter<T>)
}

//5、定义事件发射器接口
interface Emitter<T{
    //发送 onNext 事件
    fun onNext(t: T)
    //发送 onError 事件
    fun onError(e: Throwable)
    //发送 onComplete 事件
    fun onComplete()
}

//6、定义 create 操作符的实现类
class ObservableCreate<T>(var source: ObservableOnSubscribe<T>): Observable<T>() {
  
    //实现父类订阅观察者的方法
    override fun subscribeActual(downStream: Observer<T>) {
       //可以看到只要一订阅,首先就会接收 onSubscribe 事件
        downStream.onSubscribe()
       //通过 ObservableOnSubscribe 里面的 Emitter 进行事件的发送,完成被观察者发送事件的解耦
        source.subscribe(CreateEmitter(downStream))
    }

    //事件发射器实现类,可以看到传入了下游的观察者来接收我们发射的事件
    class CreateEmitter<T>(var downStream: Observer<T>): Emitter<T>{

        override fun onNext(t: T) {
            downStream.onNext(t)
        }

        override fun onError(e: Throwable) {
            downStream.onError(e)
        }

        override fun onComplete() {
            downStream.onComplete()
        }
    }
}

//7、测试
fun main(){
    Observable.create(object : ObservableOnSubscribe<String>{
        override fun subscribe(emitter: Emitter<String>) {
            //发射 onNext 事件
            emitter.onNext("erdai666")
            //发射 onComplete 事件
            emitter.onComplete()
        }
    }).subscribe(object : Observer<String>{
        override fun onSubscribe() {
            println("onSubscribe")
        }

        override fun onNext(t: String) {
            println("onNext:$t")
        }

        override fun onError(e: Throwable) {
        }

        override fun onComplete() {
            println("onComplete")
        }
    })
}
//打印结果
onSubscribe
onNext:erdai666
onComplete

ok,上述代码就是 create 操作符的实现,大家如果没看明白可以多看几遍,也可以直接把我上面的代码直接拷贝到一个 kt 文件中去运行

2.4、map 操作符实现

map 是一个转换操作符,它能把一种类型转为为另外一种类型,如:Int 转换为 String。

它的主要实现:观察者模式 + 装饰者模式 + 泛型

//1、定义一个抽象装饰类,注意里面泛型的使用
abstract class AbstractObservableWithUpstream<T,U>(var source: ObservableSource<T>): Observable<U>()

//2、定义一个类型转换的接口
interface Function<T,U{
    //传入 T 类型,返回 U 类型
    fun apply(t: T): U
}

//3、定义 map 操作符的实现类
class ObservableMap<T,U>(source: ObservableSource<T>,var function: Function<T,U>): AbstractObservableWithUpstream<T,U>(source) {

    //实现父类订阅观察者的方法
    override fun subscribeActual(observer: Observer<U>) {
       //接收 onSubscribe 事件
        observer.onSubscribe()
       //完成事件的转换
        source.subscribe(MapObserver(function,observer))
    }

    //MapObserver 接收 function 对类型进行转换,downStream 对事件进行接收
    class MapObserver<T,U>(var function: Function<T,U>,var downStream: Observer<U>): Observer<T>{
        override fun onSubscribe() {
        }

        override fun onNext(t: T) {
            //核心:当接收到 T 类型,调用 function.apply 转换为 U 类型
            val u: U = function.apply(t)
            downStream.onNext(u)
        }

        override fun onError(e: Throwable) {
            downStream.onError(e)
        }

        override fun onComplete() {
            downStream.onComplete()
        }

    }
}

//4、Observable 中增加相应的调用方法
fun <U> map(function: Function<T, U>): ObservableMap<T,U>{
    return ObservableMap(this, function)
}

//5、测试
fun main(){
    Observable.create(object : ObservableOnSubscribe<String>{
        override fun subscribe(emitter: Emitter<String>) {
            emitter.onNext("erdai666")
            emitter.onComplete()
        }
    })
        .map(object : Function<String,String>{
            override fun apply(t: String): String {
                return "map 转换:$t"
            }
        })
        .subscribe(object : Observer<String>{
        override fun onSubscribe() {
            println("onSubscribe")
        }

        override fun onNext(t: String) {
            println("onNext:$t")
        }

        override fun onError(e: Throwable) {
        }

        override fun onComplete() {
            println("onComplete")
        }
    })
}

//打印结果
onSubscribe
onNext:map 转换:erdai666
onComplete

2.5、flatMap 操作符实现

flatMap 操作符的实现其实和 map 类似,只不过是把:Function<T, U> 中的 U 变成了 ObservableSource ,将一种类型转换为了一个被观察者的类型,被观察者的类型又可以进行一系列的转换,因此能拆分更细的粒度:

//1、定义 flatMap 操作符的实现类
class ObservableFlatMap<T,U>(source: ObservableSource<T>,var function: Function<T,ObservableSource<U>>): AbstractObservableWithUpstream<T,U>(source) {

    override fun subscribeActual(observer: Observer<U>) {
        observer.onSubscribe()
        source.subscribe(FlatMapObserver(function,observer))
    }

    //FlatMapObserver 接收 function 对类型进行转换,downStream 对事件进行接收
    class FlatMapObserver<T,U>(var function: Function<T,ObservableSource<U>>, var downStream: Observer<U>): Observer<T>{
        override fun onSubscribe() {
        }

        override fun onNext(t: T) {
            //核心:当接收到 T 类型,调用 function.apply 转换为 ObservableSource<U> 类型
            val u: ObservableSource<U> = function.apply(t)
            //对 u 进行更细粒度的拆分,在让下游观察者进行接收
            u.subscribe(object : Observer<U>{
                override fun onSubscribe() {

                }

                override fun onNext(t: U) {
                    downStream.onNext(t)
                }

                override fun onError(e: Throwable) {

                }

                override fun onComplete() {

                }
            })
        }

        override fun onError(e: Throwable) {
            downStream.onError(e)
        }

        override fun onComplete() {
            downStream.onComplete()
        }
    }
}

//2、Observable 中增加相应的调用方法
fun <U> flatMap(function: Function<T,ObservableSource<U>>): ObservableFlatMap<T,U>{
    return ObservableFlatMap(this,function)
}

//3、测试
fun main(){
    Observable.create(object : ObservableOnSubscribe<String>{
        override fun subscribe(emitter: Emitter<String>) {
            emitter.onNext("erdai666")
            emitter.onComplete()
        }
    }).flatMap(object : Function<String,ObservableSource<String>>{
        override fun apply(t: String): ObservableSource<String> {
            return Observable.create(object : ObservableOnSubscribe<String>{
                override fun subscribe(emitter: Emitter<String>) {
                    emitter.onNext("flatMap:$t")
                }
            })
        }

    })
        .subscribe(object : Observer<String>{
        override fun onSubscribe() {
            println("onSubscribe")
        }

        override fun onNext(t: String) {
            println("onNext:$t")
        }

        override fun onError(e: Throwable) {
        }

        override fun onComplete() {
            println("onComplete")
        }
    })
}

//打印结果
onSubscribe
onNext:flatMap:erdai666
onComplete

2.6、subscribeOn 操作符实现

subscribeOn 主要是用来决定我们订阅观察者是在哪个线程执行

//1、定义一个抽象的调度器
abstract class Scheduler {
  
    abstract fun createWorker(): Worker
    
    //定义一个抽象的 Worker
    abstract class Worker{
       //真正决定线程执行
        abstract fun schedule(runnable: Runnable)
    }
}

//2、定义调度器的实现类,我们主要实现两种:
//2.1、AndroidMainScheduler:Android 主线程
//可以看到我们就是使用 Handler 将线程切换到主线程
class AndroidMainScheduler(var handler: Handler): Scheduler() {
    override fun createWorker(): Worker {
        return AndroidMainWorker(handler)
    }
    
    class AndroidMainWorker(var handler: Handler): Worker(){
        override fun schedule(runnable: Runnable) {
            handler.post(runnable)
        }
    }
}

//2.2、NewThreadScheduler:开启一个新的子线程
//可以看到我们就是使用线程池来执行 runnable
class NewThreadScheduler(var executorService: ExecutorService): Scheduler() {

    override fun createWorker(): Worker {
        return NewThreadWork(executorService)
    }
  
    class NewThreadWork(var executorService: ExecutorService): Worker(){
        override fun schedule(runnable: Runnable) {
            executorService.execute(runnable)
        }
    }
}

//3、定义一个线程调度器的工具类,类似 RxJava 的调用
class Schedulers {
  
    companion object{
       //切换到子线程
        fun newThread(): NewThreadScheduler{
            return NewThreadScheduler(Executors.newScheduledThreadPool(2))
        }
    
       //切换到主线程
        fun mainThread(): AndroidMainScheduler{
            return AndroidMainScheduler(Handler(Looper.getMainLooper()))
        }
    }
}

//4、定义 subscribeOn 操作符实现类
class ObservableSubscribeOn<T>(source: ObservableSource<T>,var scheduler: Scheduler): AbstractObservableWithUpstream<T,T>(source) {

    override fun subscribeActual(observer: Observer<T>) {
       //接收订阅事件
        observer.onSubscribe()
       //创建 Worker 决定我们代码所执行的线程
        val worker = scheduler.createWorker()
        worker.schedule(SubscribeTask(SubscribeOnObserver(observer)))
    }


    //可以看到,Runnable 里面就只做了一个订阅操作,因此 subscribeOn 会决定我们订阅观察者的线程
    inner class SubscribeTask(var observer: SubscribeOnObserver<T>): Runnable{
        override fun run() {
            source.subscribe(observer)
        }
    }
  
    //如果我们没有使用 observeOn 切换线程,那么观察者接收事件的线程也会由 subscribeOn 线程决定
    class SubscribeOnObserver<T>(var observer: Observer<T>): Observer<T>{
        override fun onSubscribe() {
        }

        override fun onNext(t: T) {
            observer.onNext(t)
        }

        override fun onError(e: Throwable) {
            observer.onError(e)
        }

        override fun onComplete() {
            observer.onComplete()
        }

    }
}

//5、Observable 中增加相应的调用方法
fun subscribeOn(scheduler: Scheduler): ObservableSubscribeOn<T>{
    return ObservableSubscribeOn(this,scheduler)
}

//6、测试
fun main(){
    Observable.create(object :ObservableOnSubscribe<String>{
        override fun subscribe(emitter: Emitter<String>) {
            emitter.onNext("erdai666")
            emitter.onComplete()
            println("subscribe:${Thread.currentThread().name}")
        }

    }).subscribeOn(Schedulers.newThread())
        .subscribe(object : Observer<String>{
            override fun onSubscribe() {
                println("onSubscribe:${Thread.currentThread().name}")
            }

            override fun onNext(t: String) {
                println("onNext:$t")
                println("onNext:${Thread.currentThread().name}")
            }

            override fun onError(e: Throwable) {
                println("onError:${Thread.currentThread().name}")
            }

            override fun onComplete() {
                println("onComplete")
                println("onComplete:${Thread.currentThread().name}")
            }
        })
}

//打印结果
onSubscribe:main
onNext:erdai666
onNext:pool-1-thread-1
onComplete
onComplete:pool-1-thread-1
subscribe:pool-1-thread-1

分析一下上面的打印结果:

1、onSubscribe 是在一开始订阅就触发的,此时 Worker 都还没创建,因此是在主线程执行的

2、因为我们没有使用 observeOn 对观察者接收事件的线程进行切换,所以 onNext,onComplete 接收事件的线程由 subscribeOn 切换的线程决定,

3、subscribe 在我们实际订阅观察者的方法里会执行它,因此是由 subscribeOn 切换的线程决定

2.7、observeOn 操作符实现

observeOn 是用来决定我们观察者接收事件是在哪个线程执行,实现相对复杂一点,它内部使用了一个队列来存储发送过来的 onNext 事件,然后通过 While 循环对队列中的事件进行处理,具体大家可以看我下面的实现,写了详细的注释

//1、定义 observeOn 操作符实现类
class ObservableObserveOn<T>(source: ObservableSource<T>, var scheduler: Scheduler): AbstractObservableWithUpstream<T, T>(source) {

    override fun subscribeActual(observer: Observer<T>) {
       //接收订阅事件
        observer.onSubscribe()
        val worker = scheduler.createWorker()
        source.subscribe(ObserveOnObserver(observer,worker))
    }

    class ObserveOnObserver<T>(var observer: Observer<T>, var worker: Scheduler.Worker, var queue: Deque<T>? = null): Observer<T>,Runnable {

        //标记是否事件都已经接收,一般在 onError 或 onComplete 时标记
        @Volatile
        var done = false

        //记录 onError 的异常
        @Volatile
        var throwable: Throwable? = null

        //是否能结束 While 循环:例如观察者接收了 onError 或 onComplete 事件,就可以结束循环了
        @Volatile
        var over = false

        init {
            //如果队列为空,则新建
            if(queue == null){
                queue = ArrayDeque()
            }
        }

        override fun onSubscribe() {
        }

        override fun onNext(t: T) {
            if(done)return
            //将接收的 onNext 事件加入队列中
            queue?.offer(t)
            //执行调度
            schedule()
        }

        override fun onError(e: Throwable) {
            if(done)return
            //记录异常
            throwable = e
            //标记接收事件完成
            done = true
            //执行调度
            schedule()

        }

        override fun onComplete() {
            if(done)return
            //标记接收事件完成
            done = true
            //执行调度
            schedule()
        }

        //可以看到这里进行了任务的执行,由 observeOn 决定执行的线程
        private fun schedule() {
            worker.schedule(this)
        }

        override fun run() {
            drainNormal()
        }

        //实际最终的逻辑就是在这个方法里面进行处理
        private fun drainNormal() {
            //取当前的队列
            val q = queue
            //取观察者
            val obs = observer

            //while 循环取出队列里面的 onNext 事件
            while (true){
                //取 done 标记
                val d = done
                //从队列中取出元素并出队
                val t = q?.poll()
                //如果 t 为 null 表示队列里面没有事件了
                val empty = t == null
                //检查是否能终止 While 循环
                if(checkTerminated(d,empty,obs)){
                    return
                }

                //如果队列为空,跳出 While 循环
                if(empty)break

                //观察者接收 onNext 事件
                t?.apply {
                    obs.onNext(this)
                }
            }

        }

        //检查是否能终止 While 循环
        private fun checkTerminated(d: Boolean, empty: Boolean, obs: Observer<T>)Boolean {
            if(over){
                //如果能结束了,清空队列
                queue?.clear()
                return true
            }

            //如果已经完成事件的发送
            if(d){
                val e = throwable
                if(e != null){
                    //如果有 onError 事件,标记结束,并接收 onError 事件
                    over = true
                    obs.onError(e)
                }else if(empty){
                    //如果队列为空,标记结束,并接收 onComplete 事件
                    over = true
                    obs.onComplete()
                    return true
                }
            }
            return false
        }
        
    }


//2、Observable 中增加相应的调用方法
fun observeOn(scheduler: Scheduler): ObservableObserveOn<T>{
    return ObservableObserveOn(this,scheduler)
}

//3、测试,因为涉及到 Handler 切换到主线程,我们这里放到 Activity 里面去测试
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        Observable.create(object : ObservableOnSubscribe<String> {
            override fun subscribe(emitter: Emitter<String>) {
                emitter.onNext("erdai666")
                emitter.onComplete()
                println("subscribe:${Thread.currentThread().name}")
            }

        })
            .subscribeOn(Schedulers.newThread())
            .observeOn(Schedulers.mainThread())
            .subscribe(object : Observer<String> {
                override fun onSubscribe() {
                    println("onSubscribe:${Thread.currentThread().name}")
                }

                override fun onNext(t: String) {
                    println("onNext:$t")
                    println("onNext:${Thread.currentThread().name}")
                }

                override fun onError(e: Throwable) {
                    println("onError:${Thread.currentThread().name}")
                }

                override fun onComplete() {
                    println("onComplete")
                    println("onComplete:${Thread.currentThread().name}")
                }
            })
    }
}

//打印结果
onSubscribe:main
subscribe:pool-2-thread-1
onNext:erdai666
onNext:main
onComplete
onComplete:main

分析一下上面的打印结果:

1、onSubscribe 是在一开始订阅就触发的,此时 Worker 都还没创建,因此是在主线程执行的

2、subscribe 在我们实际订阅观察者的方法里会执行它,因此是由 subscribeOn 切换的线程决定

3、observeOn 决定了观察者接收事件所在的线程,因此 onNext,onComplete 是在主线程执行的

三、RxJava 框架流思想设计

我们通过一段代码来分析 RxJava 的框架流设计:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    
       //create 操作符
        Observable.create(object : ObservableOnSubscribe<String> {
            override fun subscribe(emitter: Emitter<String>) {
                emitter.onNext("erdai666")
                emitter.onComplete()
                println("subscribe:${Thread.currentThread().name}")
            }

        })
           //map 操作符
            .map(object : Function<String,String>{
                override fun apply(t: String): String {
                    println("map:${Thread.currentThread().name}")
                    return "map:$t"
                }
            })
           //flatMap 操作符
            .flatMap(object : Function<String,ObservableSource<String>>{
                override fun apply(t: String): ObservableSource<String> {
                    println("flatMap:${Thread.currentThread().name}")
                    return Observable.create(object : ObservableOnSubscribe<String>{
                        override fun subscribe(emitter: Emitter<String>) {
                            emitter.onNext("flatMap:$t")
                        }
                    })
                }

            })
           //subscribeOn 操作符
            .subscribeOn(Schedulers.newThread())
           //observeOn 操作符
            .observeOn(Schedulers.mainThread())
           //订阅
            .subscribe(object : Observer<String> {
                override fun onSubscribe() {
                    println("onSubscribe:${Thread.currentThread().name}")
                }

                override fun onNext(t: String) {
                    println("onNext:$t")
                    println("onNext:${Thread.currentThread().name}")
                }

                override fun onError(e: Throwable) {
                    println("onError:${Thread.currentThread().name}")
                }

                override fun onComplete() {
                    println("onComplete")
                    println("onComplete:${Thread.currentThread().name}")
                }
            })
    }
}

3.1、链式构建流

特点:从上往下

使用一段伪代码来分析 RxJava Observable 的构建

val source = ObservableOnSubscribe()
//create 操作符
Observable.create(souce) ---> observable0 = ObservableCreate(source)
//map 操作符
observable0.map() ---> observable1 = ObservableMap(observable0)
//flatMap 操作符
observable1.flatMap() ---> observable2 = ObservableFlatMap(observable1)
//subscribeOn 操作符
observable2.subscribeOn() ---> observable3 = ObservableSubscribeOn(observable2)
//observeOn 操作符
observable3.observeOn() ---> observable4 = ObservableObserveOn(observable3)

有没有发现规律:我们在上游创建的 Observable(被观察者) 会被传入到下游。这就是典型的装饰者模式的应用,它的特点就是从上往下,无限套娃,动态的达到功能的增强

3.2、订阅流

特点:从下往上

使用一段伪代码来分析 RxJava 订阅的过程

val observe5 = Observer(){}...
observable4.subscribe(observe5) ---> observable4.subscribeActual(observe5)

//observeOn 操作符
val observe4 = ObserveOnObserver(observe5)
observable3.subscribe(observe4) ---> observable3.subscribeActual(observe4)

//subscribeOn 操作符
val observe3 = SubscribeOnObserver(observe4)
observable2.subscribe(observe3) ---> observable2.subscribeActual(observe3)

//flatMap 操作符
val observe2 = FlatMapObserver(observe3)
observable1.subscribe(observe2) ---> observable1.subscribeActual(observe2)

//map 操作符
val observe1 = MapObserver(observe2)
observable0.subscribe(observe1) ---> observable0.subscribeActual(observe1)

//create 操作符
val emitter = CreateEmitter(observe1)
source.subscribe(emitter)

有点递归的意思哈

可以发现规律:我们在下游创建的 Observable 订阅时,会递归先执行上游的订阅,因此订阅流的特点就是从下往上

3.3、回调流

特点:从上往下

我们分析订阅流可以发现,观察者对象是从下往上传的,因此当 emitter 发送事件时,接收的顺序:

//create 操作符
emitter -> observe1

//map 操作符
observe1 -> observe2

//flatMap 操作符
observe2 -> observe3

//subscribeOn 操作符
observe3 -> observe4

//observeOn 操作符
observe4 -> observe5

可以看到:当 emitter 发送事件后,观察者收到事件的顺序是从上往下的

上面这三个流就是 RxJava 框架流的一个思想设计,对于你理解 RxJava 非常重要,如果没看明白,多看几遍

3.4、问题回顾

掌握了 RxJava 框架流,我们回顾一下前面提到的两个问题:

1、如果有多个 subscribeOn ,会是一种什么情况?为啥?

答:只有最上面那个 subscribeOn 切换的线程才会生效。因为 subscribeOn 的作用就是决定你订阅所执行的线程,而订阅流是从下往上的,因此你如果使用多个 subscribeOn 对线程进行切换,最终生效的只会是最上面那个

2、如果有多个 observeOn ,会是一种什么情况?为啥?

答:同理,只有最下游那个 observeOn 切换的线程才会生效。因为回调流是从上往下的,所以如果你创建了多个观察者接收事件,最终生效的只会是最下面那个

好好体会下下面这个例子:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Observable.create(object : ObservableOnSubscribe<String> {
            override fun subscribe(emitter: Emitter<String>) {
                emitter.onNext("erdai666")
                emitter.onComplete()
                println("subscribe:${Thread.currentThread().name}")
            }

        })
            .subscribeOn(Schedulers.newThread())
            .map(object : Function<String, String> {
                override fun apply(t: String): String {
                    println("map:${Thread.currentThread().name}")
                    return "map:$t"
                }

            })
            .subscribeOn(Schedulers.mainThread())
            .subscribeOn(Schedulers.newThread())
            .subscribeOn(Schedulers.mainThread())
            .observeOn(Schedulers.newThread())
            .observeOn(Schedulers.mainThread())
            .observeOn(Schedulers.newThread())
           .observeOn(Schedulers.mainThread())
            .subscribe(object : Observer<String> {
                override fun onSubscribe() {
                    println("onSubscribe:${Thread.currentThread().name}")
                }

                override fun onNext(t: String) {
                    println("onNext:$t")
                    println("onNext:${Thread.currentThread().name}")
                }

                override fun onError(e: Throwable) {
                    println("onError:${Thread.currentThread().name}")
                }

                override fun onComplete() {
                    println("onComplete")
                    println("onComplete:${Thread.currentThread().name}")
                }

            })
    }
}

//打印结果
onSubscribe:main
map:pool-2-thread-1
subscribe:pool-2-thread-1
onNext:map:erdai666
onNext:main
onComplete
onComplete:main

四、RxLifeCycle

实现 RxLifeCycle 之前,我们需要了解一下 compose 操作符

4.1、compose 操作符介绍

compose 操作符作用:传入一个上游的被观察者返回一个下游的被观察者,能起到一个代码复用的逻辑

注意:下面使用的是 RxJava 包下的类

class MyTransformer<T: Any>: ObservableTransformer<T,T{

    override fun apply(upstream: Observable<T>): ObservableSource<T> {
       //完成订阅和回调线程的切换
        return upstream.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
    }
}


//实际应用
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Observable.create(object : ObservableOnSubscribe<String>{
            override fun subscribe(emitter: ObservableEmitter<String>) {
                emitter.onNext("erdai666")
                emitter.onComplete()
                println("subscribe:${Thread.currentThread().name}")
            }
        }) 
           //compose 操作符需要传入一个 ObservableTransformer 类型的对象
            .compose(MyTransformer())
            .subscribe(object : Observer<String>{
                override fun onSubscribe(d: Disposable) {
                    println("onSubscribe:${Thread.currentThread().name}")
                }

                override fun onNext(t: String) {
                    println("onNext $t")
                    println("onNext:${Thread.currentThread().name}")
                }

                override fun onError(e: Throwable) {
                    println("onError:${Thread.currentThread().name}")
                }

                override fun onComplete() {
                    println("onComplete")
                    println("onComplete:${Thread.currentThread().name}")
                }
            })
    }
}

//打印结果
onSubscribe:main
subscribe:RxCachedThreadScheduler-1
onNext erdai666
onNext:main
onComplete
onComplete:main

4.2、RxLifeCycle 实现

我们上面写的代码是存在内存泄漏的,如果我们使用 RxJava 在 Activity 做一个网络请求,此时用户退出了当前 Activity ,但是网络请求还在继续,那么此时就会产生内存泄漏,因此我们需要在做网络请求的时候感知 Activity 的生命周期去做相应的逻辑处理,那么此时 RxLifeCycle 就派上用场了,直接上代码:

//1、RxLifeCycle 实现类
//1.1、它实现了 LifecycleEventObserver,因此可以感知 LifecycleOwner 的声明周期
//1.2、它实现了 ObservableTransformer,因此我们可以使用 compose 操作符
class RxLifeCycle<T: Any>: LifecycleEventObserver,ObservableTransformer<T,T{

    var compositeDisposable = CompositeDisposable()

    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        if(event == Lifecycle.Event.ON_DESTROY){
            //监听到 LifecycleOwner 生命周期为 Destroy 时,移除 Disposable 容器中的所有 Disposable 对象
            compositeDisposable.clear()
        }
    }

    override fun apply(upstream: Observable<T>): ObservableSource<T> {
        return upstream.doOnSubscribe{
            //将 Disposable 加入 Disposable 容器
            compositeDisposable.add(it)
        }
    }

    companion object{
       //传入 LifecycleOwner,和 RxJava 进行生命周期绑定
        fun <T: Any> bindToDestroy(owner: LifecycleOwner): RxLifeCycle<T>{
            val rxLifeCycle = RxLifeCycle<T>()
            owner.lifecycle.addObserver(rxLifeCycle)
            return rxLifeCycle
        }
    }
}

//2、使用
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Observable.create(object : ObservableOnSubscribe<String>{
            override fun subscribe(emitter: ObservableEmitter<String>) {
                emitter.onNext("erdai666")
                emitter.onComplete()
                println("subscribe:${Thread.currentThread().name}")
            }
        }) 
            .compose(MyTransformer())
           //绑定生命周期,防止内存泄漏
           .compose(RxLifeCycle.bindToDestroy(this))
            .subscribe(object : Observer<String>{
                override fun onSubscribe(d: Disposable) {
                    println("onSubscribe:${Thread.currentThread().name}")
                }

                override fun onNext(t: String) {
                    println("onNext $t")
                    println("onNext:${Thread.currentThread().name}")
                }

                override fun onError(e: Throwable) {
                    println("onError:${Thread.currentThread().name}")
                }

                override fun onComplete() {
                    println("onComplete")
                    println("onComplete:${Thread.currentThread().name}")
                }
            })
    }
}

五、RxBus

实现 RxBus 前,我们需要先了解一下 Subject

5.1、Subject 介绍

1、Subject 既可以表示一个被观察者也可以表示一个观察者,实际它就是继承了 Observable 抽象类并实现了 Observer 接口

2、Subject 主要分为四种:

1、AsyncSubject

2、BehaviorSubject

3、PublishSubject

4、ReplaySubject

5.1.1、AsyncSubject

特点:事件发射无论是在订阅前还是后,都只会接收最后一个事件

fun main(){
    val subject = AsyncSubject.create<String>()
    subject.onNext("A")
    subject.onNext("B")
    subject.subscribe {
        println(it)
    }
    subject.onNext("C")
    subject.onNext("D")
    subject.onComplete()
}

//打印结果
D

5.1.2、BehaviorSubject

特点:接收订阅前最后一个事件以及订阅后的所有事件

fun main(){
    val subject = BehaviorSubject.create<String>()
    subject.onNext("A")
    subject.onNext("B")
    subject.subscribe {
        println(it)
    }
    subject.onNext("C")
    subject.onNext("D")
    subject.onComplete()
}

//打印结果
B
C
D

5.1.3、PublishSubject

特点:只接收订阅后的所有事件

fun main(){
    val subject = PublishSubject.create<String>()
    subject.onNext("A")
    subject.onNext("B")
    subject.subscribe {
        println(it)
    }
    subject.onNext("C")
    subject.onNext("D")
    subject.onComplete()
}

//打印结果
C
D

5.1.4、ReplaySubject

特点:事件发射无论是在订阅前还是后,都会被全部接收

fun main(){
    val subject = ReplaySubject.create<String>()
    subject.onNext("A")
    subject.onNext("B")
    subject.subscribe {
        println(it)
    }
    subject.onNext("C")
    subject.onNext("D")
    subject.onComplete()
}

//打印结果
A
B
C
D

5.2、RxBus 实现

我们在日常开发中,事件总线用的最多的可能是 EventBus,殊不知 RxJava 也能通过 Subject 实现事件总线的功能,而且使用起来比 EventBus 还简单一些:

//1、RxBus 实现类
object RxBus {
    //定义一个 PublishSubject 类型的 Subject,只接收订阅后的事件
    private val subject: Subject<Any> = PublishSubject.create<Any>().toSerialized()
    
    //接收事件
    fun <T: Any> receive(clazz: Class<T>): Observable<T>{
        return subject.ofType(clazz)
    }

    //发送事件
    fun post(o: Any){
        subject.onNext(o)
    }
}

//2、使用
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        RxBus.receive(String::class.java)
           //绑定生命周期,防止内存泄漏
            .compose(RxLifeCycle.bindToDestroy(this))
            .subscribe {
                println(it)
            }

        RxBus.post("erdai666")
    }
}

//打印结果
erdai666

六、总结

本篇文章我们由浅入深对 RxJava 进行了全面的介绍:

1、介绍了 RxJava 中使用的两种设计模式:

1、变种的观察者模式

2、装饰者模式

2、手撸了 RxJava 核心操作符的实现,希望你能举一反三,其它操作符的实现也是类似的套路

3、介绍了 RxJava 框架流思想设计:

1、链式构建流:从上往下

2、订阅流:从下往上

3、回调流:从上往下

4、介绍了 compose 操作符并扩展实现了 RxLifeCycle

5、介绍了 Subject 并扩展实现了 RxBus

好了,本篇文章到这里就结束了,希望能给你带来帮助 🤝

感谢你阅读这篇文章

你的点赞,评论和关注是对我巨大的鼓励!

如果有问题,欢迎加我微信:sweetying520 ,在技术学习,个人成长的道路上,我们一起前进!


原文始发于微信公众号(sweetying):一篇就够系列:RxJava 核心解密

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/61318.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!