此篇文章分析RXjava中的lift方法(Observable类中)
首先,先分析较为简单的map方法,分析下面这段代码:
ServerAPI.getAPIClient().getYachtIndex().map(new Func1<TMResponse<YachtIndexBean>, YachtIndexBean>() {
@Override
public YachtIndexBean call(TMResponse<YachtIndexBean> yachtIndexBeanTMResponse) {
return yachtIndexBeanTMResponse.getData();
}
});
其中:
public interface TMGolfAPI {
@GET("/index.php?r=api/yachtSiteIndex")
Observable<TMResponse<YachtIndexBean>> getYachtIndex();
}
调用map 方法时,直接进入
public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
return lift(new OperatorMap<T, R>(func));
}
PS一句:
大家都知道
Func1接口中泛型是T是指输入类型,R输出类型,暂这么理解吧。
public interface Func1<T, R> extends Function {
R call(T t);
}
那么看到,map()方法中的Fun1又对参数做了限定。<? super T, ? extends R>
这里有一个比较重要的概念,即:
super 在泛型中用于对参数类型的限定,不能对返回类型做限定。
extendse 用于对返回类型的限定, 不能对参数类型做限定。
栗子可以看我转载的另一篇文章: Java 泛型
咳咳,继续。
map 方法直接返回return lift(new OperatorMap<T, R>(func));
再进去看一下OperatorMap类。OperatorMap<T, R> implements Operator<R, T>
,OperatorMap又继承了Operator。Operator又是Func1的子类。
*/
public interface Operator<R, T> extends Func1<Subscriber<? super R>, Subscriber<? super T>> {
// cover for generics insanity
}
那么先记住,*OperatorMap 就是一个Func1接口的实现。且输入和输出都是一个Subscriber();*
重点:public final class OperatorMap<T, R> implements Operator<R, T>
它在类声名的时候,直接把参数调换了。
那么回调方法中,OperatorMap.call()返回了一个Subscriber,类型是原有的类型:
@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);
}
}
};
}
注意:* o.onNext(transformer.call(t));* 这里的o指是的最终转换完成,observable 被订阅的subscriber。
接下来重点分析 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 = hook.onLift(operator).call(o);
try {
// new Subscriber created and being subscribed with so 'onStart' it
st.onStart();
onSubscribe.call(st);
} catch (Throwable e) {
// localized capture of errors rather than it skipping all operators
// and ending up in the try/catch of the subscribe method which then
// prevents onErrorResumeNext and other similar approaches to error handling
Exceptions.throwIfFatal(e);
st.onError(e);
}
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// if the lift function failed all we can do is pass the error to the final Subscriber
// as we don't have the operator available to us
o.onError(e);
}
}
});
}
最终要返回的是一个Observable 对象,实际上,这里调用了lift方法,都是重建一个Observable,所以的操作都会在这个Observable的call方法中进行转换,这里直接new 了一个。
它的call方法中。
Subscriber<? super T> st = hook.onLift(operator).call(o);
那么这个hook指的是最外层的observable 也就是Observable<TMResponse<YachtIndexBean>>
。
hook.onLift(operator)
直接返回,operator。(理解成直接operator.call(o));
public <T, R> Operator<? extends R, ? super T> onLift(final Operator<? extends R, ? super T> lift) {
return lift;
}
返回了OperatorMap中的Subscriber<? super T>。
到这里, 其实思路非常的清晰了。我们再来理一理:
首先:1. ServerAPI.getAPIClient().getYachtIndex();返回Observable ,我们暂叫Observable 1.
调用Observable.map();时,map方法会创建一个新Observable。在我们subscribe订阅的时候。立即执行 里面的call 方法。
@Override
public void call(Subscriber<? super R> o) {
try {
Subscriber<? super T> st = hook.onLift(operator).call(o);
try {
// new Subscriber created and being subscribed with so 'onStart' it
st.onStart();
onSubscribe.call(st);
} catch (Throwable e) {
// localized capture of errors rather than it skipping all operators
// and ending up in the try/catch of the subscribe method which then
// prevents onErrorResumeNext and other similar approaches to error handling
Exceptions.throwIfFatal(e);
st.onError(e);
}
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// if the lift function failed all we can do is pass the error to the final Subscriber
// as we don't have the operator available to us
o.onError(e);
}
}
然后调用operator.call(); 并把Subscriber传进去。
在operator).call()
方法中,做了一个代理。
operator里面返回的Subscriber 的onNext 会调用最终的Subscriber.onNext();
@Override
public void onNext(T t) {
try {
o.onNext(transformer.call(t));
} catch (Throwable e) {
Exceptions.throwOrReport(e, this, t);
}
}
返回的Subscriber这时并不会执行,因为它的call方法还没被调用。最后再用最初的Observable 1去调用。onSubscribe.call(st)。
如此一来, map()就发挥中间数据转换的作用。并且参数已经由神奇的泛型帮我们处理好了。