java核心源码_手写Rxjava核心源码

你是不是看过了很多分析Rxjava源码的文章,但依旧无法在心中勾勒出Rxjava原理的样貌。是什么让我们阅读Rxjava源码变得如此艰难?是Rxjava的代码封装,以及各种细节问题的解决。

本文我把Rxjava的各种封装、抽象统统剥去,只专注于基本的事件变换。帮助大家理解事件变换大概是做了件什么事情时。有了基本的轮廓今后再去看源码,考虑其它问题就会更加容易。

说明:这是一篇Rxjava源码分析的入门文章。旨在让读者脑中有个概念Rxjava最主要干了件什么事情,几个常用操作符的主要原理。今后再去看其它源码分析文章或源码能够更容易理解。因此本文先不去考虑Rxjava源码中复杂的抽象封装,线程间通信,onComplete、onError、dispose等方法,仅专注于“onNext”的最基本调用方式。

本文目录:

手写Rxjava核心代码,create,nullMap(核心)操作符

map,observeOn,subscribeOn,flatMap操作符

响应式编程思想的理解

手写Rxjava核心代码,create,nullMap操作符

Create操作符

我们先来看一个最简单调用

MainActivity.java

Observable.create(new Observable() {

@Override

public void subscribe(Observer observer) {

observer.onNext("hello");

observer.onNext("world");

observer.onComplete();

}

}).subscribe(new Observer() {

@Override

public void onNext(String s) {

Log.e("yxj",s);

}

@Override

public void onComplete() {

Log.e("yxj","onComplete");

}

});

Observable.java

public abstract class Observable {

public abstract void subscribe(Observer observer);

public static Observable create(Observable observable){

return observable;

}

}

Observer.java

public interface Observer {

void onNext(T t);

void onComplete();

}

本篇文章我把Observable称为“节点”,Observer称为“处理者”,一是因为我被观察者、被观察者、谁订阅谁给绕晕了,更重要的是我觉得这个名称比较符合Rxjava的设计思想。

Observable调用create方法创建一个自己,重写subscribe方法说:如果 我有一个处理者Observer,我就把“hello”,“world”交给它处理。

Observable调用了subscribe方法,真的找到了Observer。于是兑现承诺,完成整个调用逻辑。

这里是“如果”有处理者,需要subscribe方法被调用时,“如果”才成立。Rxjava就是建立在一系列的“如果”(回调)操作上的。

“nullMap”操作符(核心)

1.创建一个observable

2.调用空map操作符做变换

3.交给observer处理

MainActivity.java

Observable.create(new Observable() {

@Override

public void subscribe(Observer observer) {

observer.onNext("hello");

observer.onNext("world");

observer.onComplete();

}

})

.nullMap()

.subscribe(new Observer() {

@Override

public void onNext(String s) {

Log.e("yxj",s);

}

@Override

public void onComplete() {

Log.e("yxj","onComplete");

}

});

nullMap()等价于 下面这段代码

即把上个节点的数据不做任何修改的传递给下一节点的map操作

.map(new Function() {

@Override

public String apply(String s) throws Exception {

return s;

}

})

"nullMap"操作符在Rxjava源码里并不存在,是我方便大家理解Rxjava运行机制写出来的。

因为nullMap操作是一个 base变换操作,map,flatMap,subscribeOn,observeOn操作符都是在nullMap上修改而来。所以Rxjava的变换的基础就是nullMap操作符。

Observable.java

// 这就是Rxjava的变换核心

public Observable nullMap() {

return new Observable() {

@Override

public void subscribe(final Observer observerC) {

Observer observerB = new Observer() {

@Override

public void onNext(T t) {

observerC.onNext(t);

}

@Override

public void onComplete() {

observerC.onComplete();

}

};

Observable.this.subscribe(observerB);

}

};

}

“nullMap”操作符做了件什么事情:

上一个节点Observable A调用nullMap(),在内部new一个新的节点Observable B。

节点B重写subscribe方法,说"如果"自己有操作者Observer C,就new一个操作者Observer B,然后让节点A subscribe 操作者B。

节点A subscribe 操作者B,让操作者B执行onNext方法。操作者B的onNext方法内部,调用了操作者C的onNext。从而完成了整个调用。

请注意2中的”如果“。意味着,当节点B中的subscribe方法没有被调用的时候,2,3步骤都不会执行(他们都是回调),没有Observer B,节点A也不会调用subscribe方法。

接下来分两种情况:

节点B调用了subscribe方法,则执行2,3,完成整个流程。

节点B调用nullMap,从新走一遍1,2,3步骤,相当于节点B把任务交给了下一个节点C。

概况一下就是:

Observable每调用一次操作符,其实就是创建一个新的Observable。新Observable内部通过subscribe方法“逆向的”与上一Observable关联。在新Observable中的new出来的Observer内的onNext方法中做了和下一个Observer之间的关联。

map,observeOn,subscribeOn,flatMap操作符

接下来让我们看看这4个操作符,仅仅是在nullMap中做了小改动而已。

操作符源码

map操作符

Observable.java

public Observable map(final Function function) {

return new Observable() {

@Override

public void subscribe(final Observer observer1) {

Observable.this.subscribe(new Observer() {

@Override

public void onNext(T t) {

R r = function.apply(t); // 仅仅在这里加了变换操作

observer1.onNext(r);

}

@Override

public void onComplete() {

observer1.onComplete();

}

});

}

};

}

和“nullMap”相比,仅仅加了一行代码function.apply() 方法的调用。

observeOn操作符

Observable.java

public Observable observeOn() {

return new Observable() {

@Override

public void subscribe(final Observer observer) {

Observable.this.subscribe(new Observer() {

@Override

public void onNext(final T t) {

//模拟切换到主线程(通常上个节点是运行在子线程的情况)

handler.post(new Runnable() {

@Override

public void run() {

observer.onNext(t);

}

});

}

@Override

public void onComplete() {

}

});

}

};

}

与“nullMap”相比,修改了最内部的onNext方法执行所在的线程。Rxjava源码会更加灵活,observerOn方法参数让你可以指定切换到的线程,其实就是传入了一个线程调度器,用于指定observer.onNext()方法要在哪个线程执行。原理是一样的。我这里就简写,直接写了切换到主线程,这你肯定能看明白。

subscribeOn操作符

Observable.java

public Observable subscribeOn() {

return new Observable() {

@Override

public void subscribe(final Observer observer) {

new Thread() {

@Override

public void run() {

// 这里简写了,没有new Observer做中转,github上有完整代码

Observable.this.subscribe(observer);

}

}.start();

}

};

}

将上一个节点切换到新的线程,修改了Observable.this.subscribe()运行的线程,Observable.this指的是调用subscribeOn()的Observable,即上一个节点。因此subscribeOn操作符修改了上一个节点的运行所在的线程

flatMap操作符

public Observable flatMap(final Function> function) {

return new Observable() {

@Override

public void subscribe(final Observer observer) {

Observable.this.subscribe(new Observer() {

@Override

public void onNext(T t) {

try {

Observable observable = function.apply(t);

observable.subscribe(observer);

} catch (Exception e) {

e.printStackTrace();

}

}

@Override

public void onComplete() {

}

});

}

};

}

flatmap和map极为相似,只不过function.apply()的返回值是一个Observable。

Observable是一个节点,既可以用来封装异步操作,也可以用来封装同步操作(封装同步操作 == map操作符)。所以这样就可以很方便的写出一个

耗时1操作 —> 耗时2操作 —> 耗时3操作...的操作

到这里相信大家已经对Rxjava怎样运行,几个常见的操作符内部基本原理有了初步的理解,本文的目的就已经达到了。在之后看Rxjava源码或者其它分析文章时,就能少受各种变换的干扰。接下来就可以思考Rxjava是如何对各个Observable做封装,线程之间如何通信,onComplete、onError、dispose等方法如何实现了。

响应式编程思想的理解

响应式编程是一种面向数据流和变化传播的编程范式。

直接看这句话其实不太容易理解。让我们换个说法,实际编程中是什么会干扰我们,使我们无法专注于数据流和变化传播呢?答案是:异步,它会让我们的代码形成嵌套,不够顺序化。

因为异步,我们的业务逻辑会写成回调嵌套的形式,导致过一段时间看自己代码看不懂,语义化不强,不是按着顺序一个节点一个节点的往下执行的。

Rxjava将所有的业务操作变成一步一步,每一步不管你是同步、异步,统统用一个节点包裹起来,节点与节点之间是同步调用的关系。如此,整个代码的节点都是按顺序执行的。

限于作者个人水平有限,本文部分表述难免有不对之处,请留言指出,相互交流。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值