既然是进阶知识,假定你已经拥有RxJava相关的使用经验,所以我就不多逼逼它的好了,本文将结合源码,来分析一个Observable是如何发出事件的。
Context
- rxjava:1.0.16
- 本文贴出的rxjava源码都是精简过的,旨在简洁地表达源码意图
1. 概念准备,何为上/下游事件?
上/下游事件,是在Rx中用来描述事件所处位置的,这其实是一个相对的概念。我使用一段示例代码来解释这个概念。
Observable
.just("hello")
.map(s->s+=‘OK’)
.subscribe(Action1->{...})
复制代码
按照我们上面代码来分析,just
在map
的上面,而Action1
在map
的下面,数据传递流程是这样的:just->map->Action1
,所以对于map
来说,just
是它的上游,而Action1
是它的下游。在Rx中,事件是从上游流向下游的。
2. 上游事件是如何产生的?
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
,而这个Observable
的onSubcribe
也是新的,他叫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.onSubscribe
为JustOnSubscribe
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来达到的呢?
不久的将来,我也会通过源码来冷静分析一波