适应RxJava2思维习惯

RxJava有几个重要关键字,即函数响应式编程,观察者模式,事件发射,消费等等。以下这段话摘自其他文章Android 响应式编程 RxJava2 完全解析。鸣谢作者。

响应式编程的组成为Observable/Operator/Subscriber,RxJava在响应式编程中的基本流程>如下:
这个流程,可以简单的理解为:Observable -> Operator1 -> Operator2 -> Operator3 -> Subscriber

  1. Observable发出一系列事件,他是事件的产生者;
  2. Subscriber负责处理事件,他是事件的消费者;
  3. Operator是对Observable发出的事件进行修改和变换;
  4. 若事件从产生到消费不需要其他处理,则可以省略掉中间的Operator,从而流程变为 Obsevable -> Subscriber;
  5. Subscriber通常在主线程执行,所以原则上不要去处理太多的事务,而这些复杂的处理则交给Operator;

假如中间没有Operator,流程只有Observable到Subscriber,那么画UML类图,跟踪源码,来看函数执行顺序。
适应RxJava2思维习惯_第1张图片

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 observer) {
    CreateEmitter parent = new CreateEmitter(observer);
    observer.onSubscribe(parent);

    try {
        source.subscribe(parent);
    } catch (Throwable ex) {
        Exceptions.throwIfFatal(ex);
        parent.onError(ex);
    }
}
  1. 把new出来然后传进来的Observer对象包装成CreateEmitter类,变量名为parent
  2. 调用上述Observer的onSubscribe函数,参数是上述CreateEmitter对象parent
  3. 调用ObservableCreate的成员变量source(ObservableOnSubscribe类型)的subscribe函数,传入上述parent变量

所以在不使用操作符和线程切换,只创建被观察者和观察者,并且相互绑定,函数的执行顺序是这样的:

  1. 执行Observer的onSubscribe函数,这个方法是程序员自己写的。
@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 observer;

    CreateEmitter(Observer 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
    }
});

实际的执行顺序是:

  1. 先执行Observer的OnSubscribe方法,理解为”即将订阅时,做某某事“
  2. 执行Observable内的ObservableOnSubscribe成员的subscribe方法,理解为”此处订阅”。程序员在此处结合实际业务逻辑,调用
    Observer的onNext、onError、onComplete的任意组合。onNext、onError、onComplete被统称为事件发射,也就不难理解subscribe函数的参数为什么叫做发射器。
  3. 根据第2步中程序员自己定义的事件发射顺序,逐个执行(消费)掉那些事件。

例子中的subscribe方法中,先发射onNext,再发射onComplete,实际上是可以任意的。比如,for循环60次,每次执行某些逻辑后发射onNext,循环结束后发射onComplete,如果中途有异常或错误,发射onError。是不是似曾相识?思考一下app登录页面的短信验证码倒计时页面。

注意:真正的短信验证码倒计时页面不会使用这么笨的方法来发射事件,因为RxJava提供了丰富的操作符来简化典型的使用场景,比如interval。这也是它收到追捧的原因之一。
本篇介绍的是创建Observable->创建Observer–>订阅,这种简单结构的源码分析,下一篇,将拆解 创建Observable->操作符–>创建Observer–>订阅结构的源码。

你可能感兴趣的:(开源组件)