RxJava有几个重要关键字,即函数响应式编程,观察者模式,事件发射,消费等等。以下这段话摘自其他文章Android 响应式编程 RxJava2 完全解析。鸣谢作者。
响应式编程的组成为Observable/Operator/Subscriber,RxJava在响应式编程中的基本流程>如下:
这个流程,可以简单的理解为:Observable -> Operator1 -> Operator2 -> Operator3 -> Subscriber
- Observable发出一系列事件,他是事件的产生者;
- Subscriber负责处理事件,他是事件的消费者;
- Operator是对Observable发出的事件进行修改和变换;
- 若事件从产生到消费不需要其他处理,则可以省略掉中间的Operator,从而流程变为 Obsevable -> Subscriber;
- Subscriber通常在主线程执行,所以原则上不要去处理太多的事务,而这些复杂的处理则交给Operator;
假如中间没有Operator,流程只有Observable到Subscriber,那么画UML类图,跟踪源码,来看函数执行顺序。
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
IDAL idal;
try {
idal = NeptuneLiteUser.getInstance().getDal(application);
} catch (Exception e) {
LogUtil.e(e);
throw e;
}
if (!emitter.isDisposed()) {
emitter.onNext(idal);
emitter.onComplete();
}
}
}).subscribe(new Observer() {
@Override
public void onSubscribe(Disposable d) {
mCompositeDisposable.add(d);
}
@Override
public void onNext(Boolean aBoolean) {
//nothing
if (aBoolean) {
initParamService();
}
}
@Override
public void onError(Throwable e) {
//nothing
}
@Override
public void onComplete() {
//nothing
}
});
调用Observable接口的静态方法create创建了一个ObservableCreate被观察者,
RxJavaPlugins.onAssembly(new ObservableCreate(new ObservableOnSubscribe(){}) )
然后通过Observable的subscribe方法将被观察者ObservableCreate和新创建出来的观察者new Observer绑定起来,前者传递给后者消费。
话分两头,一头是RxJavaPlugins.onAssembly, 另一头是Observable的subscribe函数。
RJavaPlugins.onAssembly内部调用了静态成员变量onObservableAssembly的apply函数,经过转换,返回的应该还是new ObservableCreate(new ObservableOnSubscribe(){}) 这个Observable对象。
另一头Observable的subscribe函数只有两行关键代码,
observer = RxJavaPlugins.onSubscribe(this, observer);
subscribeActual(observer);
RxJavaPlugins.onSubscribe函数内部调用的也是一个转换函数,但是形式与RxJavaPlugins.onAssembly内部调用的不太一样。
subscribeActual是一个Observable的抽象方法,最终会调用到子类ObservableCreate的subscribeActual方法,在分析这个具体的subscribeActual函数做的三件事之前,
我们看看ObservableCreate这个类的定义
public final class ObservableCreate extends Observable {
final ObservableOnSubscribe source;
public ObservableCreate(ObservableOnSubscribe source) {
this.source = source;
}
它有一个成员变量叫source, 类型是ObservableOnSubscribe,这个成员变量通过构造函数赋值的。也就是通过Observable的静态方法create创建被观察者时传入的那个匿名对象。
前面已经讨论过
RxJavaPlugins.onAssembly(new ObservableCreate(new ObservableOnSubscribe(){}) )
来看看ObservableCreate的subscribeActual做了哪三件事
@Override
protected void subscribeActual(Observer super T> observer) {
CreateEmitter parent = new CreateEmitter(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
所以在不使用操作符和线程切换,只创建被观察者和观察者,并且相互绑定,函数的执行顺序是这样的:
@Override
public void onSubscribe(Disposable d) {
mCompositeDisposable.add(d);
}
这里的Disposable形参d其实是CreateEmitter对象,CreateEmitter实现了Disposable接口。
2. 执行ObservableOnSubscribe的subscribe函数
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
IDAL idal;
try {
idal = NeptuneLiteUser.getInstance().getDal(application);
} catch (Exception e) {
LogUtil.e(e);
throw e;
}
if (!emitter.isDisposed()) {
emitter.onNext(idal);
emitter.onComplete();
}
}
这里的ObservableEmitter形参 emitter其实也是CreateEmitter对象,CreateEmitter实现了ObservableEmitter接口。
在这个subscribe方法也是程序员自己写的。具体到这个例子,先进行了一些初始化,然后调用了CreateEmitter的onNext和onComplete方法。
我们又要到CreateEmitter这个类中去看看这两个方法的具体实现。这个是ObservableCreate的静态内部类,实现了ObservableEmitter和Disposable两个接口
static final class CreateEmitter
extends AtomicReference
implements ObservableEmitter, Disposable {
private static final long serialVersionUID = -3434801548987643227L;
final Observer super T> observer;
CreateEmitter(Observer super T> observer) {
this.observer = observer;
}
@Override
public void onNext(T t) {
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
if (!isDisposed()) {
observer.onNext(t);
}
}
@Override
public void onComplete() {
if (!isDisposed()) {
try {
observer.onComplete();
} finally {
dispose();
}
}
}
CreateEmitter的onNext和onComplete方法其实转交回Observer的onNext呢onComplete方法了,只是会先判空,再判断dispose标记。这里的Observer就是开始new出来的观察者。这里的dispose标记可以理解为流的开关。
总结
在RxJava2的以下代码基本结构中
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {//2
}).subscribe(new Observer() {
@Override
public void onSubscribe(Disposable d) {//1
}
@Override
public void onNext(Boolean aBoolean) {//3
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {//4
}
});
实际的执行顺序是:
例子中的subscribe方法中,先发射onNext,再发射onComplete,实际上是可以任意的。比如,for循环60次,每次执行某些逻辑后发射onNext,循环结束后发射onComplete,如果中途有异常或错误,发射onError。是不是似曾相识?思考一下app登录页面的短信验证码倒计时页面。
注意:真正的短信验证码倒计时页面不会使用这么笨的方法来发射事件,因为RxJava提供了丰富的操作符来简化典型的使用场景,比如interval。这也是它收到追捧的原因之一。
本篇介绍的是创建Observable->创建Observer–>订阅,这种简单结构的源码分析,下一篇,将拆解 创建Observable->操作符–>创建Observer–>订阅结构的源码。