我们先来看一段最基本的代码,分析这段代码在RxJava中是如何实现的。
Observable.OnSubscribe onSubscriber1 = new Observable.OnSubscribe() {
@Override
public void call(Subscriber super String> subscriber) {
subscriber.onNext("1");
subscriber.onCompleted();
}
};
Subscriber subscriber1 = new Subscriber() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
}
};
Observable.create(onSubscriber1)
.subscribe(subscriber1);
首先我们来看一下Observable.create的代码
public final static Observable create(OnSubscribe f) {
return new Observable(hook.onCreate(f));
}
protected Observable(OnSubscribe f) {
this.onSubscribe = f;
}
直接就是调用了Observable的构造函数来创建一个新的Observable对象,这个对象我们暂时标记为observable1,以便后面追溯。
同时,会将我们传入的OnSubscribe对象onSubscribe1保存在observable1的onSubscribe属性中,这个属性在后面的上下文中很重要,大家留心一下。
接下来我们来看看subscribe方法。
public final Subscription subscribe(Subscriber super T> subscriber) {
return Observable.subscribe(subscriber, this);
}
private static <T> Subscription subscribe(Subscriber super T> subscriber, Observable<T> observable) {
...
subscriber.onStart();
hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber);
return hook.onSubscribeReturn(subscriber);
}
可以看到,subscribe之后,就直接调用了observable1.onSubscribe.call方法,也就是我们代码中的onSubscribe1对象的call方法
,传入的参数就是我们代码中定义的subscriber1对象。call方法中所做的事情就是调用传入的subscriber1对象的onNext和onComplete方法。
这样就实现了观察者和被观察者之间的通讯,是不是很简单?
public void call(Subscriber super String> subscriber) {
subscriber.onNext("1");
subscriber.onCompleted();
}
注:从上面可以看出来,onstart方法是在call方法之前调用,hook.onSubscribeStart代理了call方法的调用,因此subscriber方法的onNext方法调用所在的线程和onstart的线程不一定一样,onstart的调用在这条链中只调用一次,并且线程和Observable所在线程一致。
从上看出,订阅者模式分为三个部分:
Observable被观察者,
onSubscriber联系观察者和被观察者的中介,
Subscriber观察者。
onSubscriber类需要复写call函数,这个类定义了被观察者的事件分发机制,比如上面的:
@Override
public void call(Subscriber super String> subscriber) {
subscriber.onNext("1");
subscriber.onCompleted();
}
这里定义了观察者在接收到事件之后,所做出的动作顺序,执行一次onNext(),在执行一次onCompleted()。
Subscriber类 需要实现Subscriber的三个方法,他们是接收到事件到结束时间周期过程需要执行的具体逻辑。
new Subscriber() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
}
};
其实map的操作就是调用lift操作实现的,我们先看看map操作是怎么执行的。
Observable.OnSubscribe onSubscriber1 = new Observable.OnSubscribe() {
@Override
public void call(Subscriber super String> subscriber) {
subscriber.onNext("1");
subscriber.onCompleted();
}
};
Subscriber subscriber1 = new Subscriber() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Integer i) {
}
};
Func1 transformer1 = new Func1() {
@Override
public Integer call(String s) {
return Integer.parseInt(s);
}
};
Observable.create(onSubscriber1)
.map(transformer1)
.subscribe(subscriber1);
和第一个例子不同在subscribe操作之前,我做了map操作,对数据进行了转换,使得最后subscriber得到的integer类型的参数。
public final Observable map(Func1 super T, ? extends R> func) {
return lift(new OperatorMap(func));
}
这里有个新类
其中的OperatorMap
类型其实是继承自Operator
,Operator
又是继承自Func1
public final class OperatorMap<T, R> implements Operator<R, T>
public interface Operator<R, T> extends Func1<Subscriber super R>, Subscriber super T>>
这里可以明显的看出来,OperatorMap
的T类型是返回参数类型和R类型是函数参数类型,而Func1
的功能也可以看出来是要接受一个subscriber,然后产生一个新的类型的subscriber。具体是怎么实现的呢?接下来在继续看lift到底做了什么:
public final Observable lift(final Operator extends R, ? super T> operator) {
return new Observable(new OnSubscribe() {
@Override
public void call(Subscriber super R> o) {
Subscriber super T> st = hook.onLift(operator).call(o);
st.onStart();
onSubscribe.call(st);
}
});
}
语句hook.onLift(operator).call(o);
调用的是下面这个方法:
@Override
public Subscriber super T> call(final Subscriber super R> o) {
return new Subscriber(o) {
@Override
public void onNext(T t) {
o.onNext(transformer.call(t));
}
};
}
首先就返回了一个新的observable类型,它的尖括号类型刚好就是map的Func1的返回类型,内部改写的call方法首先就是 ,返回一个新的subscriber(这个新的订阅者其实内部的onNext逻辑是通过Transformer将原始的事件类型转化成指定的类型,然后在调用原始subscriber订阅者的onNext()方法(这样的做法类似于我们所说的java动态代理),这样原始的string类型的事件被转化成integer类型之后,在新的subscriber订阅者中的onNext()函数中调用原始的onsubscriber的onNext()函数,并且integer类型作为参数传递给原始onsubscriber的onNext()函数,我们通过上面就知道了,lift操作其实将上层的事件的参数类型装换成下层的subscriber的onNext()函数的参数之后,通过静态代理的手段产生新的subscriber,将下层的subscriber代理起来,通过调用lift中的新的subscriber的onNext方法进而将事件传递给了下层subscriber的onNext方法,而新产生的subscriber又作为参数传递给了上层的observable的onSubscriber的call方法。
自底向上:当观察者订阅事件的时候,其实将新创建出来的subscriber作为参数放到上层的onsubscriber中,这样如果上层还是lift操作,onsubscriber的call还是会新建subscriber作为参数传递给上上层onsubscriber中,也就是下层的观察者被代理后,传递给上层,以此类推直到被观察者为之,接着就会真正执行call方法,
自顶向下:这样当上层的onSubscriber的call()函数被调用后,那么就先调用新产生的subscriber(也就是subscriber代理对象)的onNext()方法,新产生的subscriber内部又会调用原始的subscriber(被代理的subscriber对象)的onNext()方法,多个lift操作也是类似的原理,一层一层的代理,最终就会调用原始的subscriber对象的onNext()的方法。下面有个图可以说明lift的操作流程:
也就是订阅者订阅操作是自底向上(层层代理被传递到顶层),事件分发是自顶向下(一层一层的内部调用最终调用到了订阅者的方法)。
lift也是订阅者只不过在接受事件之后,又向下层继续分发事件。
动态图表示就是如下: