Lift是RxJava中比较核心的操作。RxJava中的绝大多数操作符都是通过lift完成的,而Lift本质上是作了一个类似于中转的作用,接收前一个Observable的事件,作处理,然后发送给后一个subscriber;
这次我们通过查看Map操作的实现,来了解lift的原理。
首先还是让我们回顾下subscribe操作的原理:
private static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
//合法性校验
(省略)
//onStart()回调
subscriber.onStart();
//调用observable.onSubscribe.call()方法
try {
observable.onSubscribe.call(subscriber);
return subscriber;
} catch (Throwable e) {
//解绑
return Subscriptions.unsubscribed();
}
}
//以上代码省略部分非核心逻辑
由以上代码可以知道一个通用的RxJava订阅操作中:
Observable的内部成员变量OnSubscribe的call方法的参数(下面代码的第3行),就是subscribe方法的参数(下面代码的第7行),也就是这个Observable订阅的subscriber。
Observable的内部成员变量OnSubscribe的call方法的参数(下面代码的第3行),就是subscribe方法的参数(下面代码的第7行),也就是这个Observable订阅的subscriber。
Observable的内部成员变量OnSubscribe的call方法的参数(下面代码的第3行),就是subscribe方法的参数(下面代码的第7行),也就是这个Observable订阅的subscriber。
1 Observable.create(new Observable.OnSubscribe<String>() { 2 @Override 3 public void call(Subscriber<? super String> subscriber) { 4 subscriber.onNext("Hello world"); 5 subscriber.onCompleted(); 6 } 7 }).subscribe(new Subscriber<String>() { 8 @Override 9 public void onStart() { 10 super.onStart(); 11 } 12 @Override 13 public void onCompleted() { 14 } 15 @Override 16 public void onError(Throwable e) { 17 } 18 @Override 19 public void onNext(String o) { 20 System.out.println(o); 21 } 22 });
回顾了最基本的订阅操作之后,让我们看下Map的操作符的实现:
举个简单的例子:新建一个originObservable,然后进行map操作,获取每一个String的length,然后把length发送给lastSubscriber
Observable originObservable = Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { subscriber.onNext("Haaaaaaa"); subscriber.onCompleted(); } });
1 originObservable.map(new Func1<String, Integer>() { 2 @Override 3 public Integer call(String string) { 4 return string.length(); 5 } 6 }).subscribe(lastSubscriber);
直接看map的实现:
public final <R> Observable<R> map(Func1<? super T, ? extends R> func) { return lift(new OperatorMap<T, R>(func)); }
这样的话,上述的例子实际上就变成了这样:
originObservable.lift(new OperatorMap<String, Integer>(new Func1<String, Integer>() { @Override public Integer call(String string) { return string.length(); } })).subscribe(lastSubscriber);
然后我们再看lift的实现:
public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) { return new Observable<R>(new OnSubscribe<R>() { @Override public void call(Subscriber<? super R> o) { try { Subscriber<? super T> st = operator.call(o); try { st.onStart(); onSubscribe.call(st); } catch (Throwable e) { st.onError(e); } } catch (Throwable e) { o.onError(e); } } }); } //以上代码省略了部分非主要逻辑
首先观察lift的源码,我们可以发现:
- Lift内部new了一个Observable,(暂且称之为NewLiftObservable)并且作为Lift方法的返回值。
- NewLiftObservable的成员变量OnSubscribe的call方法内部,调用operator.call(Subscriber)方法,得到了一个新的Subscriber。(暂且称之为OperatorCallSubscriber)
这样再看我们再结合我们的例子,就会发现,订阅lastSubscriber的原来是Lift内部new出来的那个Observable,即:NewLiftObervable,所以例子也就变成了下面这样:
new Observable<R>(new OnSubscribe<R>() { @Override public void call(Subscriber<? super R> o) { try { Subscriber<? super T> st = operator.call(o); try { st.onStart(); onSubscribe.call(st); } catch (Throwable e) { st.onError(e); } } catch (Throwable e) { o.onError(e); } } }).subscribe(lastSubscriber);
再结合subscribe的原理,我们可以知道上述中call方法的o参数,其实就是lastSubscriber对象,
那么上述operator.call实际操作的也是lastSubscriber对象,即如下面这样:
Subscriber<? super T> st = operator.call(lastSubscriber);
所以OperatorCallSubscriber是operator调用call方法去操作lastSubscriber生成的。
所以OperatorCallSubscriber是operator调用call方法去操作lastSubscriber生成的。
所以OperatorCallSubscriber是operator调用call方法去操作lastSubscriber生成的。
然后我们继续看NewLiftOperator的OnSubscribe的call方法内部还做了哪些事,
调用OperatorCallSubscriber的onStart方法
把OperatorCallSubscriber作为OnSubscribe的call方法的参数传递进去。
这里有一点需要注意:
onSubscribe.call(st);
这句代码中的ObSubscribe不是NewLiftObervable的成员变量,而是originObservable的。因为实际上调用lift方法的是originObservable。(这一点需要想通)
所以originObservable生成的代码变成了这样:
Observable originObservable = Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> OperatorCallSubscriber) { OperatorCallSubscriber.onNext("Haaaaaaa"); OperatorCallSubscriber.onCompleted(); } });
其实也就是:
Observable originObservable = Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> oprator.call(lastSubscriber)) { oprator.call(lastSubscriber).onNext("Haaaaaaa"); oprator.call(lastSubscriber).onCompleted(); } });
对比下没有调用map操作的结果:
Observable originObservable = Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> lastSubscriber) { lastSubscriber.onNext("Haaaaaaa"); lastSubscriber.onCompleted(); } });
很明显,可以发现map操作的左右就是调用operator.call方法把lastSubscriber给包装了下,
再看下operator哪来的:观察lift的源码,很明显operator是lift的参数,在本例中也就是OperatorMap对象,即map操作符的实现,
那么看下OperatorMap的源码吧:
public final class OperatorMap<T, R> implements Operator<R, T> { private final Func1<? super T, ? extends R> transformer; public OperatorMap(Func1<? super T, ? extends R> transformer) { this.transformer = transformer; } @Override public Subscriber<? super T> call(final Subscriber<? super R> o) { return new Subscriber<T>(o) { @Override public void onCompleted() { o.onCompleted(); } @Override public void onError(Throwable e) { o.onError(e); } @Override public void onNext(T t) { try { o.onNext(transformer.call(t)); } catch (Throwable e) { Exceptions.throwOrReport(e, this, t); } } }; } }
通过前面的例子,很明显可以看到,源码中的transformer就是我们使用map的时候传入的func;
然后再看下OperatorMap的call方法,很简单,就是把call方法传入的Subscriber进行了简单的包装,并且返回了一个新的Subscriber,结合前面的结论:
OperatorCallSubscriber是operator调用call方法去操作lastSubscriber生成的。
因此
OperatorCallSubscriber实际上只是简单包装了lastSubscriber,并且调用在OperatorCallSubscriber的onNext方法的时候,先把参数通过map的func做变换,再传递给lastSubscriber的onNext方法。
这样就完成了map的功能,上述也就是lift的原理的简单阐述。