RxJava中map的源码分析

本文的分析基于RxJava1.1.5版本,map的主要作用是用来将一个对象转换成另外一个对象,它的实现基于了RxJava中非常重要的lift()方法

1、下面先写一个简单的例子

Observable.create(new Observable.OnSubscribe() {
            @Override
            public void call(Subscriber subscriber) {
                subscriber.onNext("1");
                subscriber.onCompleted();
            }
        }).map(new Func1() {
            @Override
            public Integer call(String s) {
                return Integer.valueOf(s);
            }
        }).subscribe(new Subscriber() {
            @Override
            public void onCompleted() {
                Log.e("TAG","---onCompleted()----");
            }

            @Override
            public void onError(Throwable e) {
                Log.e("TAG","---onError()----");
            }

            @Override
            public void onNext(Integer integer) {
                Log.e("TAG", "值为:" + integer);
            }
        });

以上是最简单的RxJava的一个试用,因为本文是分析map的过程,所以并没有编写线程调度器

2、下面是具体的分析过程:
首先:进入到map()方法的实现

public final  Observable map(Func1 func) {
        return lift(new OperatorMap(func));
    }

这里传入func1对象作为参数,返回值为lift()方法的返回值,其中在调用liftf()方法的时候,会创建一个OperatorMap对象作为参数传入,而OperatorMap继承自Operator接口,我的理解是,这里主要是为了将func1对象作为参数,然后在OperatorMap对象中创建新的Subscriber对象(新的观察者对象),这里新的Subscriber对象称为subscriber_new

接着进入到liftf()方法中

public final  Observable lift(final Operator operator) {
        return new Observable(new OnSubscribeLift(onSubscribe, operator));
    }

在lift()方法中,会返回新的Observable对象(新的被观察者对象,这里先称为observable_new),同时会将原来的Observable对象中的onSubscribe和subscriber_new作为参数创建OnSubscribeLift对象,在我理解中,这个对象就是新的OnSubscribe对象,这里先称为onsubscribe_new

通过上面两步的分析可以知道,map最终的返回值是在lift()方法中创建的新的Observable对象,即observable_new对象。

接着,我们的程序会到了主线上,程序将会调用subscribe()方法,这个方法用于订阅被观察者,那么,这里观察者将不会是旧的Observable对象,而是新的Observable对象,即observable_new对象,那么我们进入到该方法内部看看,下面是subscribe()方法实现

public final Subscription subscribe(Subscriber subscriber) {
        return Observable.subscribe(subscriber, this);
    }

在该方法内部会将旧的Subscriber对象和旧的Observable对象作为参数去调用Observable.subscribe(subscriber, this)

下面接着看Observable.subscribe(subscriber, this)

static  Subscription subscribe(Subscriber subscriber, Observable observable) {
        if (subscriber == null) {
            throw new IllegalArgumentException("observer can not be null");
        }
        if (observable.onSubscribe == null) {
            throw new IllegalStateException("onSubscribe function can not be null.");
        }
        
        subscriber.onStart();
        
        if (!(subscriber instanceof SafeSubscriber)) {
            // assign to `observer` so we return the protected version
            subscriber = new SafeSubscriber(subscriber);
        }

        // The code below is exactly the same an unsafeSubscribe but not used because it would 
        // add a significant depth to already huge call stacks.
        try {
            // allow the hook to intercept and/or decorate
            hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber);
            return hook.onSubscribeReturn(subscriber);
        } catch (Throwable e) {
            //异常的处理代码省略....
        }
    }

前面的判断跳过,直接看hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber);这个调用,它的返回值为OnSubscribe对象,这个OnSubscribe对象就是新的OnSubscribe对象,即为onsubscribe_new对象,而调用它的call()方法,即调用的是OnSubscribeLift类中的call()方法,那么进入到OnSubscribeLift类中的call()方法看看,注意,这里传入的参数的旧的subscriber对象

@Override
    public void call(Subscriber o) {
        try {
            Subscriber st = hook.onLift(operator).call(o);
            try {
                // new Subscriber created and being subscribed with so 'onStart' it
                st.onStart();
                parent.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);
        }
    }

首先Subscriber st =hook.onLift(operator).call(o);这个操作,这里的onLift()方法返回的是传入的operator对象,那么这个operator对象是什么呢,它就是在之前创建的OperatorMap对象,即使新的伪subscriber对象,那么也就是说,这个操作调用的call()方法,调用的是OperatorMap类中的call()方法,传入的参数为旧的subscriber对象,下面进入OperatorMap类中的call()方法中看看

@Override
    public Subscriber call(final Subscriber o) {
        MapSubscriber parent = new MapSubscriber(o, transformer);
        o.add(parent);
        return parent;
    }

在这个方法中,首先会以旧的subscriber对象和transformer(这个transformer就是func1对象,在创建OperatorMap对象的时候传入)为参数创建新的subscriber对象,之后将该对象添加到subscriptions集合中,并且返回新的subscriber对象。那么在OnSubscribeLift类中的这个类中的call()方法中的Subscriber st = hook.onLift(operator).call(o);这个操作所获得的就是新的subscriber对象,接着回到OnSubscribeLift类中的这个类中的call()方法中,在获取到新的subscriber对象之后,它会用新的subscriber对象去调用onStart()方法,之后会执行parent.call(st);这个方法,那么这个parent是什么呢?它就是在创建OnSubscribeLift对象是传入的旧的OnSubscribe对象,那么旧的OnSubscribe对象去调用call()方法,并且传入的参数为新的subscriber对象,那么自然调用的这个call()方法就是我们在创建初始Observable对象的时候的回调的call()方法,即使以下的方法

@Override
public void call(Subscriber subscriber) {
                subscriber.onNext("1");
                subscriber.onCompleted();
            }

这里的subscriber对象已经不是原来的subscriber对象了,而是在OperatorMap类中的call()方法中创建的MapSubscriber对象(即新的subscriber对象),那么它调用的onNext()方法,自然调用的就应该是MapSubscriber类中的onNext()方法

@Override
public void onNext(T t) {
    R result;
            
    try {
        result = mapper.call(t);
    } catch (Throwable ex) {
        Exceptions.throwIfFatal(ex);
        unsubscribe();
        onError(OnErrorThrowable.addValueAsLastCause(ex, t));
        return;
    }
            
    actual.onNext(result);
}

在这个方法中,主要的作用就是将func1对象中的类型转换逻辑,作为新的参数去调用旧的subscriber对象中的onNext()方法,也就是我们自己创建的subscriber对象中的onNext()回调方法,在这里,T类型就是代表旧的数据类型,而R转换后的数据类型,mapper就是func1对象,它调用的call()方法,就是我们自己在call中写的类型转换逻辑,而actual就是旧的subscriber对象,到这里,整个流程就已经贯通了

最后,这里需要注意的就是旧的对象就是代表初始的对象,而新的对象就代表是调用map()方法的时候创建的新的对象,还有要注意的就是旧的Observable对象中的回调call()方法中的subscriber对象在经过map方法之后已经不是旧的subscriber对象了,而是新的subscriber对象

你可能感兴趣的:(RxJava中map的源码分析)