「RxJava进阶」基于源码的上游(Observable)事件产生流程分析

既然是进阶知识,假定你已经拥有RxJava相关的使用经验,所以我就不多逼逼它的好了,本文将结合源码,来分析一个Observable是如何发出事件的

Context

  • rxjava:1.0.16
  • 本文贴出的rxjava源码都是精简过的,旨在简洁地表达源码意图

1. 概念准备,何为上/下游事件?

上/下游事件,是在Rx中用来描述事件所处位置的,这其实是一个相对的概念。我使用一段示例代码来解释这个概念。

Observable
    .just("hello")
    .map(s->s+=‘OK’)
    .subscribe(Action1->{...})
复制代码

按照我们上面代码来分析,justmap的上面,而Action1map的下面,数据传递流程是这样的:just->map->Action1,所以对于map来说,just是它的上游,而Action1是它的下游。在Rx中,事件是从上游流向下游的。


2. 上游事件是如何产生的?

我将选择一个较简单的Create Operator-- just来作为例子。

Observable
    .just("hello")
    .subscribe(Action1->{...})
复制代码

2.1 精简过后的just(T t)源码

public static <T> Observable<T> just(final T value) {
    return ScalarSynchronousObservable.create(value);
}

....

// 现阶段先不管Scalar到底是个啥,我们知道
// SynchronousObservable是一个同步的Observable就够了

-- ScalarSynchronousObservable.java
public static <T> ScalarSynchronousObservable<T> create(T t) {
    return new ScalarSynchronousObservable<T>(t);
}

protected ScalarSynchronousObservable(final T t) {
    super(new JustOnSubscribe<T>(t));
    this.t = t;
}

-- Observable.java
public class Observable<T> {

    final OnSubscribe<T> onSubscribe;

    protected Observable(OnSubscribe<T> f) {
        this.onSubscribe = f;
    }
    
    .....
}

复制代码

结论1: just()调用完之后,返回的是一个新的Observable,而这个ObservableonSubcribe也是新的,他叫JustOnSubscribe,然而这个t,就是我们传进来的"hello"。 目前为止,我们已经有一个Observable,和两个onSubcriber了,一个是ScalarSynchronousObservable生成的,一个是我们传入subscribe()中的。

在刚刚的分析中,我们并没有看到触发Subscriber的逻辑,我们刚刚猜想,是subscribe方法促使“Hello”传递到Action1的,那么我们来看看Observable.subscribe方法的具体实现。

2.2 Observable.subscribe()


---Observable.java
public final Subscription subscribe(final Action1<? super T> onNext) {
   
    Action1<Throwable> onError = InternalObservableUtils.ERROR_NOT_IMPLEMENTED;
    Action0 onCompleted = Actions.empty();
    // 如果在subscribe中传递的是Action,而不是subscriber
    // 那么Observable内部会将Action组装成一个Subscriber(其实Subscriber内部也是由Action通过组合的方式实现的,有点像代理模式)
    return subscribe(new ActionSubscriber<T>(onNext,onError,onCompleted));
}

public final Subscription subscribe(Subscriber<? super T> subscriber) {
    // 因为just()操作符会生成一个新的Observable
    // 所以我们在链式调用中执行的subscribe方法
    // 也就是新Observable的方法
    // 要记得新Observable.onSubcribe对象也是新的,它叫JustOnSubscribe
    return Observable.subscribe(subscriber, this);
}

static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
     
        subscriber.onStart();

        try {
            //这么一来,justOnSubscribe.call()里到底执行了什么就很关键了
            justOnSubscribe.call(subscriber)
            //源码:RxJavaHooks.onObservableStart(observable,observable.onSubscribe).call(subscriber);
            
            // Subscriber是Observer的同时也是Subscription
            // 直接返回以便进行unsubscribed()操作
            return subscriber;
            //源码:RxJavaHooks.onObservableReturn(subscriber)
        } catch (Throwable e) {
            // throw exceptions 
        }
        return Subscriptions.unsubscribed();
    }
}


--- ScalarSynchronousObservable.java
static final class JustOnSubscribe<T> implements OnSubscribe<T> {
    final T value;

    JustOnSubscribe(T value) {
        this.value = value;
    }

    @Override
    public void call(Subscriber<? super T> s) {
        s.setProducer(createProducer(s, value));
    }
}

static <T> Producer createProducer(Subscriber<? super T> s, T v){
    // 这个常量我们先不管,它默认为false
    if (STRONG_MODE) {
        return new SingleProducer<T>(s, v);
    }
    //我们默认认为返回WeakSingleProducer即可
    return new WeakSingleProducer<T>(s, v);
}

复制代码

我在上面代码写了一些注释,对一些较为关键的点做了分析。 现在我们再来升华一下,做一个Observable.subscribe()调用流程的最后结论:

  • Observable.subscribe()方法中,调用了OnSubscribe.call()
  • 因为在just()中,生成了一个新的Observable对象,并且Observable.onSubscribeJustOnSubscribe
  • justOnSubscribe.call(subscriber)subscriber,是RxJava根据我们在subscribe()传递的Action1生成的ActionSubscriber。
  • justOnSubscribe.call()中,生成了一个WeakSingleProducer,并且为ActionSubscriber设置了WeakSingleProducer

接下来,我们要把目光转移到,Subscriber.setProducer()WeakSingleProducer这个类上了.

2.3 subscriber.setProducer

--- Subscriber.java
public void setProducer(Producer p) {
    // 对于本例,省略一些背压和并发控制的逻辑代码
    // 以下为精简后的源码
    producer.request(Long.MAX_VALUE);
}
复制代码

2.4 weakSingleProducer.request

static final class WeakSingleProducer<T> implements Producer {
    final Subscriber<? super T> actual;
    final T value;
    boolean once;

    public WeakSingleProducer(Subscriber<? super T> actual, T value) {
        this.actual = actual;
        this.value = value;
    }

    @Override
    public void request(long n) {
        if (once) {
            return;
        }
        if (n < 0L) {
            throw new IllegalStateException("n >= required but it was " + n);
        }
        if (n == 0L) {
            return;
        }
        once = true;
        Subscriber<? super T> a = actual;
        if (a.isUnsubscribed()) {
            return;
        }
        T v = value;
        try {
            a.onNext(v);
        } catch (Throwable e) {
            Exceptions.throwOrReport(e, a, v);
            return;
        }

        if (a.isUnsubscribed()) {
            return;
        }
        a.onCompleted();
    }
}
复制代码

我们可以在 WeakSingleProducer.request中很清晰的看到 Subscriber的回调方法的执行。我们的“Hello”字符串也是在这里传递到下游的 Action1中的。 所以,我们是时候开始总结一波了!

2.5 完整的Observable事件产生流程

示例代码回顾:

Observable
    .just("hello")
    .map(s->s+=‘OK’)
    .subscribe(Action1->{...})
复制代码
  • 所以,对以上简单的Rx代码,是如何产生事件的分析结论是:

    • just()函数会创建一个新的Observable,并且这个Observable.OnSubscribe会被设置一个JustOnSubscribe
    • Observable.subcribe()方法中,调用了JustOnSubscribe.call()
    • JustOnSubscribe.call()中,生成Producer用于处理下游最终数据的分发
  • 具体流程图如下:

2.6 废话

其实,通过这次的分析得到的结论,我们可以做很多的猜想:

  • map,flatMap这样的变换操作符的变换(Lift)流程是咋样的呢?是否也是通过包装Observable来达到的呢?
  • Schedular的调度流程是咋样的呢?是否也是通过包装Observable来达到的呢?

不久的将来,我也会通过源码来冷静分析一波

转载于:https://juejin.im/post/5ab38264518825558b3dd868

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值