RxJava的原理如此简单

本文主要从原理上去理解RxJava,不涉及复杂的操作符讲解。

 

先看个简单例子:

Observable
.create(ObservableOnSubscribe<String> {
    it.onNext("")
})//-------》 create返回的observable简称A
.subscribeOn(Schedulers.newThread())// ------》 同理这个简称B
.observeOn(Schedulers.newThread()) //-------》 简称C
.subscribe {

}

追踪Observable类,可以看出它是个抽象类,而且实现了ObservableSource接口,这接口非常重要(抽象类加接口,配合不错),先从ObservableSource最重要的方法subscribe开始理解:(只截取一部分)

@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer<? super T> observer) {
    ObjectHelper.requireNonNull(observer, "observer is null");
    try {
        observer = RxJavaPlugins.onSubscribe(this, observer);
        ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
        subscribeActual(observer);

看,接口方法subscribe中调用了subscribeActual,这是Observable的抽象方法,先解释一下大部分的操作符都是继承了Observable,

所以每个操作符类的subscribeActual才是最核心的。

 

先看create做了啥:

public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
    ObjectHelper.requireNonNull(source, "source is null");
    return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}

就是返回了一个子类的实例,而且把ObservableOnSubscribe接口包装进去。

 

这个子类截全一点,好解释一些。先看最重要的subscribeActual,传了个Observer接口进来(先打个问号,这是什么?),创建了一个发射器,然后到最核心的是调用了source.subscribe(parent),牛逼了,此时,你可以把这个source理解为上游,上游执行了订阅方法

public final class ObservableCreate<T> extends Observable<T> {
    final ObservableOnSubscribe<T> source;

    public ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source;
    }

    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);
        observer.onSubscribe(parent);

        try {
            source.subscribe(parent);
        } catch (Throwable ex) {

 

接下来再看看subscribeOn操作符,你就会找到规律了:

public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
    final Scheduler scheduler;

    public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
        super(source);
        this.scheduler = scheduler;
    }

    @Override
    public void subscribeActual(final Observer<? super T> s) {
        final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);

        s.onSubscribe(parent);
        //直接调用调度器,说白了就是开了个线程调用了runnable,而runnable使得上游执行订阅方法
        parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
    }



final class SubscribeTask implements Runnable {
    private final SubscribeOnObserver<T> parent;

    SubscribeTask(SubscribeOnObserver<T> parent) {
        this.parent = parent;
    }

    @Override
    public void run() {
        source.subscribe(parent);
    }
}

实际它也是继承了Observable,看到subscribeAtual没,Observer接口又被包装了,而且直接调用了调度器,SubscribeTask是个Runnable,它干了啥?

额,就是执行了上游的订阅方法。

 

回顾最上面的例子,将操作符做了简称,谁先执行了subscribe?是C,下面就写个调用链路:

C.subscribe(外层Observer) --> C.subscribeActual, Observer包装进C_Observer --> C的上游B.subscribe(C_Observer)

--> B.subscribeActual,C_Observer包装进了B_Observer --> B的上游A.subscribe(B_Observer) --> A.subscribeActual,B_Observer包装进了A_Observer -->  A_Observer包装进了发射器emitter,ObservableOnSuscribe.subscribe(emitter)

看到没,我们可以在外层调用emitter的onNext等方法了。

 

至此,可以发现emitter发射数据时,observer是如何接收的,链路如下:

Emitter.onNext -> A_Observer.onNext()-> B_Observer.onNext() -> C_Observer.onNext()-> 外层observer.onNext()

通过看源码可以知道,每个操作符类中,都定义了一个静态的继承Observer接口的类,这就是包装了下游的Observer接口,并传递给上游。

 

至此,其实稍微可以总结一下RxJava的规律:

  1. 搞了个Observable抽象类,操作符的相关类都去继承它,这些类都要实现subscribeActual方法,这个方法里,上游都执行了订阅方法,看上面例子,C先执行订阅方法,再到B,再到A,所以订阅顺序就是由下往上的,而发射数据是由上往下
  2. 每个操作符的构造函数都能包装上游,是因为接口ObservableSource。
  3. 像上面说的,每个操作符类中,都定义了一个静态的继承Observer接口的类,所以才可以包装下游的Observer接口,并通过上游的subscribe传递给上游。
  4. 当链式最下面的Observable实例调用subscribe的时候,才会触发最上面的ObservableOnSuscribe.subscribe回调。
  5. 最后强调一下,不要被相同的方法名所迷惑,初学者很容易被搞懵逼的,比如ObservableOnSuscribe和ObservableSource都有个subscribe方法,但它们的参数类型不一样,而且你要区分它们各自的用途。
  6. 比较常问的一个问题,多次subscribeOn,以哪个为准?看源码就知道了
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent))); 

看到没,它是直接开了调度器的线程执行了上游的订阅方法(SubscribeTask源码在上面),举例有a、b、c 顺序的3个subscribeOn,订阅执行顺序是由下往上,c先执行,c的线程中执行了b.subscribe,b的线程中执行了a.subscribe,所以,无论你下面多少个subscribeOn,都只会以a的线程为准,所以答案是第一个的subscribeOn为准。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值