RxJava源码解析(2) —— Lift

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的原理的简单阐述。

 

posted @ 2016-03-13 20:05  pzyoung  阅读(411)  评论(0编辑  收藏  举报