以前写过 RxJava 源码分析,但是是直接对着源码分析流程,分析的也比较简单,这次从原理角度分析。 RxJava 是异步,网上介绍的都是订阅者模式,其实就是观察者模式的变种,我们先分析下 java 中自带的观察者接口 Observer 和被观察者 Observable。
这两个类的代码比较简单,Observable 中有个集合,集合中存放的是 Observer,Observable 有个notifyObservers()方法,一旦调用,就会遍历集合,执行 Observer 对象的 update() 方法。在使用中,我们可以写一个类 ObservableManager 继承 Observable,把ObservableManager做成单例,对外暴露一个封装了 notifyObservers() 的方法,供外部调用;我们在其它业务需要的地方实现 Observer 接口,通过 addObserver() 方法把它的实现类添加到 ObservableManager 中
,这样,当我们在一个地方用 ObservableManager发送了一条消息,在B地方,添加到集合中的 Observer 都能收到消息,这就是观察者模式。
RxJava 则是一个变种,它里面把发送消息的这一块,抽取了个接口出来,下面写个简单的例子,是 RxJava 的简化版。Observer 是观察者,与传统的相比,这里面有三个回调方法;Emitter 是用来发送消失,说白了就是调用 Observer 的,所以它里面的方法与 Observer 相对应;传统的观察者模式中,被观察者对外提供一个方法,这个方法直接遍历观察者,发送信息,在 RxJava 中,由于使用 Emitter 发送消息,我们不能直接创建它,需要让RxJava把它作为参数回调出来,让开发者拿到 Emitter 来调用它的方法,我们对 Emitter 进行一层封装,暴露给使用者,这里用 ObservableOnSubscribe 来实现这个功能;最后就是被观察者了,ObservableCreate 中传入一个 ObservableOnSubscribe,把它当做一个成员变量,在添加观察者的方法中,马上使用 ObservableOnSubscribe 来执行它的回调,其中的形参 Emitter 是我们自己封装的一个实现类,具体代码如下
public interface Observer<T> {
//收到消息
void onNext(T t);
//出错的回调
void onError(Throwable e);
//从订阅到消息全部发送成功
void onComplete();
}
public interface Emitter<T> {
//发送消息
void onNext(T t);
//发送异常
void onError(Throwable e);
//发送完成的信号
void onComplete();
}
public interface ObservableOnSubscribe<T> {
//为每个订阅的观察者提供一个能进行消息发送的功能,这里是给调用的地方使用的
void subscribe(Emitter<T> emitter);
}
以上三个接口,下面是重点
public class ObservableCreate <T> {
private ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source){
this.source = source;
}
//创造被观察者的实例
public static<T> ObservableCreate create(ObservableOnSubscribe<T> source){
return new ObservableCreate<>(source);
}
public void subscribe(Observer observer) {
subscribeActual(observer);
}
protected void subscribeActual(Observer observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
source.subscribe(parent);
}
static final class CreateEmitter<T> implements Emitter<T>{
Observer<T> observer;
public CreateEmitter(Observer<T> observer) {
this.observer = observer;
}
@Override
public void onNext(T t) {
observer.onNext(t);
}
@Override
public void onError(Throwable e) {
observer.onError(e);
}
@Override
public void onComplete() {
observer.onComplete();
}
}
}
写个简单的调用例子
void test1(){
ObservableCreate.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(Emitter<String> emitter) {
// 触发点
emitter.onNext("a");
emitter.onNext("b");
emitter.onComplete();
}
}).subscribe(new Observer<String>() {
@Override
public void onNext(String s) {
System.out.println("onNext: " + s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
System.out.println("onComplete" );
}
});
}
这样,本例子中的 emitter 其实就是 ObservableCreate 中的 CreateEmitter对象;ObservableCreate 中的 source,就是 test1()中的 new ObservableOnSubscribe<String>()对象,这样看起来,test1() 中先是给成员变量source赋值,执行 subscribe() 方法时,就触发了 ObservableCreate 中的 subscribeActual(Observer observer) 方法,此时的 observer 就是 test1() 中创建的 Observer<String> 对象,subscribeActual(Observer observer) 中的第二
行代码 source.subscribe(parent) 执行的是 test1()中加注释 //触发点 的位置。这种写法是观察者的变种,是相应代码,执行的顺序是从上往下的。如果还感觉晕的可以自己打断点试试。
单看上述代码,基本无价值,无外乎就是使用了接口,进行了逻辑调整,上述只是个基础,现在开始深入一点,为了方便,我把 ObservableCreate 的代码进行抽取
public abstract class Observable<T> {
public void subscribe(Observer observer) {
subscribeActual(observer);
}
protected abstract void subscribeActual(Observer<T> observer);
//创造被观察者的实例
public static<T> ObservableCreate create(ObservableOnSubscribe<T> source){
return new ObservableCreate<>(source);
}
}
public class ObservableCreate <T> extends Observable<T> {
private ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source){
this.source = source;
}
@Override
public void subscribe(Observer observer) {
super.subscribe(observer);
}
@SuppressWarnings("unchecked")
@Override
protected void subscribeActual(Observer observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
source.subscribe(parent);
}
static final class CreateEmitter<T> implements Emitter<T>{
Observer<T> observer;
public CreateEmitter(Observer<T> observer) {
this.observer = observer;
}
@Override
public void onNext(T t) {
observer.onNext(t);
}
@Override
public void onError(Throwable e) {
observer.onError(e);
}
@Override
public void onComplete() {
observer.onComplete();
}
}
}
这样的代码和之前是一样的,只不过进行了抽取,对于 Observable 其实还可以抽取一下,
public interface ObservableSource<T> {
void subscribe(Observer<T> observer);
}
public abstract class Observable<T> implements ObservableSource{
@Override
public void subscribe(Observer observer) {
subscribeActual(observer);
}
protected abstract void subscribeActual(Observer<T> observer);
//创造被观察者的实例
public static<T> ObservableCreate create(ObservableOnSubscribe<T> source){
return new ObservableCreate<>(source);
}
}
如果把它放进去,此时简化版的 RxJava 有六个类了。这六个类能干嘛呢?它还是只能执行 test1() 中的功能,如果想扩展功能怎么办,比如 RxJava 中的 map() 对数据进行转换。定义个新的数据转换接口 Function,新的被观察者类型 ObservableMap,以及在 Observable 中新添加一个创建 ObservableMap 对象的方法,注意为非静态的
public class ObservableMap<T,R> extends Observable<R>{
final ObservableSource<T> source;
final Function<T,R> function;
public ObservableMap(ObservableSource<T> source, Function<T, R> function) {
this.source = source;
this.function = function;
}
@Override
protected void subscribeActual(Observer<R> observer) {
source.subscribe(new MapObserver<>(observer,function));
}
static final class MapObserver<T,R> implements Observer<T>{
final Function<T,R> mapper;
final Observer<R> actual;
public MapObserver(Observer<R> actual, Function<T, R> mapper) {
this.actual = actual;
this.mapper = mapper;
}
@Override
public void onError(Throwable e) {
actual.onError(e);
}
@Override
public void onComplete() {
actual.onComplete();
}
@Override
public void onNext(T t) {
R apply = mapper.apply(t);
actual.onNext(apply);
}
}
}
public abstract class Observable<T> implements ObservableSource{
@Override
public void subscribe(Observer observer) {
subscribeActual(observer);
}
protected abstract void subscribeActual(Observer<T> observer);
//创造被观察者的实例
public static<T> ObservableCreate create(ObservableOnSubscribe<T> source){
return new ObservableCreate<>(source);
}
//创建被观察者
@SuppressWarnings("unchecked")
public<R> Observable<R> map(Function<T,R> function){
return new ObservableMap<>(this,function);
}
}
写个例子,运行下,大家可以看下打印的值,发现还是从上往下执行
void test2(){
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(Emitter<String> emitter) {
emitter.onNext("a");
emitter.onComplete();
}
}).map(new Function<String, String>() {
@Override
public String apply(String s) {
return s +" 111";
}
}).subscribe(new Observer<String>() {
@Override
public void onNext(String s) {
System.out.println("onNext: " + s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
System.out.println("onComplete" );
}
});
}
ObservableMap 中有两个成员变量 ObservableSource 和 Function,这里用到了装饰者模式,意思是它里面可以调用 ObservableSource 的方法,我们看看 test2() 中的代码,Observable.create() 返回对象记为 A,此时调用了 map() 方法,返回对象记为 B,那么它俩之间就产生了关联
public<R> Observable<R> map(Function<T,R> function){
return new ObservableMap<>(this,function);
}
看看 map() 类,A 是 ObservableCreate 类型,B 是 ObservableMap 类型,并且把 A 当做参数传到了 B 中,此时 B 中的成员变量 ObservableSource 和 Function 就是 A 和 test2() 中 map() 方法对应的 new Function<String, String> 匿名接口对象。再往下的 subscribe() 方法执行的是对象 B 的方法,注意了
@Override
protected void subscribeActual(Observer<R> observer) {
source.subscribe(new MapObserver<>(observer,function));
}
此时 source 是 A, MapObserver 把数据转换器 function 和观察者 observer 封装了一层,然后供 source 调用,MapObserver 实现了 Observer,它里面就是个中转站,第一反应,代理或者装饰模式,装饰比着代理,更侧重于功能的扩展,这里是装饰模式。 此时是把逻辑交割给了 A,也就是 ObservableCreate 类,执行它的 subscribeActual()方法
@Override
protected void subscribeActual(Observer observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
source.subscribe(parent);
}
此时,subscribeActual(Observer observer) 的形参 observer 就是 ObservableMap 传过来的 MapObserver 对象,到这里就接到第一阶段的分析了,source 是 test2() 中的第一行代码 create() 方法中的 ObservableOnSubscribe 对象,subscribeActual() 方法触发了 source.subscribe(parent),此时看 test2() 中代码 emitter.onNext("a"),emitter 是 subscribeActual(Observer observer) 方法中 CreateEmitter 对象,也就是执行它的 onNext(T t),这就是个代理,执行的是
observer.onNext(t),上面分析了 observer 是 ObservableMap 传过来的 MapObserver 对象,看看MapObserver的onNext(t) 方法,此时 t 的值是字符串 "a"
@Override
public void onNext(T t) {
R apply = mapper.apply(t);
actual.onNext(apply);
}
此时,mapper.apply(t) 执行了数据转换,对应 test2() 中的 new Function<String, String>() 对象中的方法,此时返回的值 apply 是字符串 "a 111" ,然后调用了actual.onNext(apply),这里 actual 是 MapObserver 构造方法传入的观察者 observer,也就是 test2() 中的 new Observer<String>() 对象,此时执行的是它的 onNext(apply)方法,到此本次分析结束。
如果我们在上面方法基础上,再提那家一个 map 转换呢?
void test3(){
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(Emitter<String> emitter) {
emitter.onNext("a");
emitter.onComplete();
}
}).map(new Function<String, String>() {
@Override
public String apply(String s) {
return s +" 111";
}
}).map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return s.length();
}
}).subscribe(new Observer<Integer>() {
@Override
public void onNext(Integer i) {
System.out.println("onNext: " + i);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
System.out.println("onComplete" );
}
});
}
注意了,数据是从上往下,数据是一层层转换,然后传给下一层。 还按照上面的分析,create() 方法创建了 ObservableCreate 对象 A,map(new Function<String, String>()) 创建了 ObservableMap 对象 B,map(new Function<String, Integer>()) 创建了 ObservableMap 对象 C,对象 C 执行了 subscribe(Observer observer) 方法,分析后,会发现和上面的逻辑一样,对象包裹关系是 A-->B-->C 一层包裹一层,当C执行 subscribe(Observer observer) 方法时,会把它本身的 observer 和 function 封装成一个新的观察者类,然后把它作为参数调用B的 subscribe(Observer observer) 方法,此时B也是ObservableMap类型,相同的操作再重复一遍,然后调用A的subscribe(Observer observer) 方法,到这里,随时到达顶点了,这里触发了发射器的回调方法,然后开始了test3()中从上往下传值,先是执行 emitter.onNext("a") 代码,此时在A中CreateEmitter对象中的observer,是B通过方法传过来的,所以就调用B对象的onNext(T t) 方法,这个方法是字符串的拼接功能,
@Override
public void onNext(T t) {
R apply = mapper.apply(t);
actual.onNext(apply);
}
// mapper 对象的实例
new Function<String, String>() {
@Override
public String apply(String s) {
return s +" 111";
}
}
R apply = mapper.apply(t) ,获得新的值后,然后又调用了 actual.onNext(apply) 这行代码,此时 actual 是C传进来的观察者,又回到了数据转换的地方
@Override
public void onNext(T t) {
R apply = mapper.apply(t);
actual.onNext(apply);
}
// mapper 对象的实例
new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return s.length();
}
这一步获取了字符串的长度,把字符串转换为了Integer类型数据,actual 就是 test3() 中的观察者了,所以就打印了日志。
看到这,其实就是 A-->B-->C,这是包裹关系,最后一个被观察者执行了 subscribe() 方法后,ObservableMap 类型的对象,都把自己的属性 Function 和 observer 给封装成新的 observer,然后传给上一层,此时调用关系就是 C-->B-->A;到达A,也就是 ObservableCreate 类型了,它内部没有用装饰模式包装一个 Observable,算是到了代码的开端的地方,从这里,开始了代码的调用,此时是调用是一层调用一层,A-->B-->C,每层都把数据传递给下一层。关于这种代码结构,
有人认为是适配器模式,但我个人觉得里面更像是个责任链模式。从这里也发现个规律,subscribeActual() 方法是数据开始的地方,用于封装该方法传形参Observer而创建的新 Observer 中的 onNext(T t) 方法,则是接收数据的地方。看到这,是否有什么联想? 关于这里说这么多,其实是为了线程切换做准备的。既然一个地方触发下一步,一个接收上面传递的数据,那么我们在这两个地方是不是可以切换线程了?
我们可以仿照 ObservableMap ,也用装饰模式,来写两个类,一个是子线程,一个是android的UI线程
public class ObservableIo<T> extends Observable<T>{
private static ExecutorService executorService = Executors.newCachedThreadPool();
final ObservableSource<T> source;
public ObservableIo(ObservableSource<T> source) {
this.source = source;
}
@Override
protected void subscribeActual(final Observer<T> observer) {
executorService.submit(new Runnable() {
@Override
public void run() {
source.subscribe(new IoObserver<>(observer));
}
});
}
static final class IoObserver<T> implements Observer<T>{
final Observer<T> actual;
public IoObserver(Observer<T> actual) {
this.actual = actual;
}
@Override
public void onError(Throwable e) {
actual.onError(e);
}
@Override
public void onComplete() {
actual.onComplete();
}
@Override
public void onNext(T t) {
actual.onNext(t);
}
}
}
public class ObservableUI<T> extends Observable<T>{
final ObservableSource<T> source;
public ObservableUI(ObservableSource<T> source) {
this.source = source;
}
@Override
protected void subscribeActual(Observer<T> observer) {
source.subscribe(new UIObserver<>(observer));
}
static final class UIObserver<T> implements Observer<T>{
final Observer<T> actual;
public UIObserver(Observer<T> actual) {
this.actual = actual;
}
@Override
public void onError(Throwable e) {
actual.onError(e);
}
@Override
public void onComplete() {
actual.onComplete();
}
@Override
public void onNext(final T t) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
actual.onNext(t);
}
});
}
}
}
Observable 类中新添两个方法
public<R> Observable<R> io(){
return new ObservableIo<>(this);
}
public<R> Observable<R> ui(){
return new ObservableUI<>(this);
}
然后看看测试代码
private void test4() {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(Emitter<String> emitter) {
Log.e("Observable", "subscribe: " + (Looper.getMainLooper() == Looper.myLooper()));
emitter.onNext("a");
}
}).map(new Function<String, String>() {
@Override
public String apply(String s) {
Log.e("Observable", "apply: " + s + " " + (Looper.getMainLooper() == Looper.myLooper()));
return s +" 111";
}
}).io()
.ui()
.subscribe(new Observer<String>() {
@Override
public void onNext(String s) {
Log.e("Observable", "onNext: " + s + " " + (Looper.getMainLooper() == Looper.myLooper()));
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
打印日志为
Observable: subscribe: false
Observable: apply: a false
Observable: onNext: a 111 true
上面的代码已经能实现线程切换了。这是一个比较粗糙的代码,其中 ObservableMap、ObservableIo、ObservableUI 都用到了装饰模式,那么类似的都可以抽取一个基类,它们里面的 Observer 包装类,也可以抽取基类,这样方便后期扩展。 上面的例子只是实现了 onNext() 方法的线程切换,这仅仅是个例子,RxJava 的代码有点多,直接看有点懵,这里提供了简易版的,它就是 RxJava 的原理,这个Demo看懂了,再去看 RxJava ,应该就容易理解了。