RxJava的源码分析

基本结构

我们先来看一段最基本的代码,分析这段代码在RxJava中是如何实现的。

Observable.OnSubscribe<String> onSubscriber1 = new Observable.OnSubscribe<String>() {
    @Override
    public void call(Subscriber<? super String> subscriber) {
        subscriber.onNext("1");
        subscriber.onCompleted();
    }
};
Subscriber<String> subscriber1 = new Subscriber<String>() {
    @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 <T> Observable<T> create(OnSubscribe<T> f) {
    return new Observable<T>(hook.onCreate(f));
}

protected Observable(OnSubscribe<T> 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<String>() {
    @Override
    public void onCompleted() {
    }

    @Override
    public void onError(Throwable e) {
    }

    @Override
    public void onNext(String s) {
    }
};

lift操作符

其实map的操作就是调用lift操作实现的,我们先看看map操作是怎么执行的。

Observable.OnSubscribe<String> onSubscriber1 = new Observable.OnSubscribe<String>() {
    @Override
    public void call(Subscriber<? super String> subscriber) {
        subscriber.onNext("1");
        subscriber.onCompleted();
    }
};
Subscriber<Integer> subscriber1 = new Subscriber<Integer>() {
    @Override
    public void onCompleted() {

    }

    @Override
    public void onError(Throwable e) {

    }

    @Override
    public void onNext(Integer i) {

    }
};
Func1<String, Integer> transformer1 = new Func1<String, Integer>() {
    @Override
    public Integer call(String s) {
        return Integer.parseInt(s);
    }
};

Observable.create(onSubscriber1)
        .map(transformer1)
        .subscribe(subscriber1);

和第一个例子不同在subscribe操作之前,我做了map操作,对数据进行了转换,使得最后subscriber得到的integer类型的参数。

public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
    return lift(new OperatorMap<T, R>(func));
}

这里有个新类
其中的OperatorMap<T, R>(func) 类型其实是继承自Operator<R, T>Operator<R, T>又是继承自Func1<Subscriber<? super R>, Subscriber<? super T>>

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> 的T类型是返回参数类型和R类型是函数参数类型,而Func1<Subscriber<? super R>, Subscriber<? super T>> 的功能也可以看出来是要接受一个subscriber,然后产生一个新的类型的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) {
            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<T>(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也是订阅者只不过在接受事件之后,又向下层继续分发事件。

动态图表示就是如下:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/u012345683/article/details/78218885