RxJava2源码分析(一)流程分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yangshuaionline/article/details/86477855

为了方便理解,先把总结的流程图发出来,有这个作为底子再去研究流程会容易的多。

在这里插入图片描述

  1. 红线为绑定观察者(Observer)之前的创建过程。
  2. 蓝线为绑定观察者时候(subscribe方法)执行的流程
  3. 绿线为被观察者发消息过程。

然后看例子:

Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) {
                boolean isMain = (Looper.myLooper() == Looper.getMainLooper());
                Log.w("打印","create是否为主线程:"+String.valueOf(isMain));
                emitter.onNext("Hello World");
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<String>() {

                    @Override
                    public void onSubscribe(Disposable d) { }

                    @Override
                    public void onNext(String s) {
                        boolean isMain = (Looper.myLooper() == Looper.getMainLooper());
                        Log.w("打印","onNext是否为主线程:"+String.valueOf(isMain));
                        Log.w("打印","onNext结果:"+s);
                    }

                    @Override
                    public void onError(Throwable t) { }

                    @Override
                    public void onComplete() { }
                });

打印结果

W/打印: create是否为主线程:false
W/打印: onNext是否为主线程:true
W/打印: onNext结果:Hello World

首先分析红线部分:红线是被观察者的创建过程。

1. 创建被观察者:

例子中new ObservableOnSubscribe()就是最原始的被观察者
这个方法作为Observable.create的参数传递过去。

2. 创建被观察者1

public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
    ObjectHelper.requireNonNull(source, "source is null");
    return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}

RxJavaPlugins.onAssembly是一个转换函数,考虑流程的时候暂不考虑。可见被观察者传递过去生成了一个新的对象ObservableCreate(被观察者1)对象,并返回被观察者1

final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
   this.source = source;
}

暂时看这些,表明被观察者是一个持有原始被观察者的对象为source。

3. 创建被观察者2

然后看调用subscribeOn方法:

public final Observable<T> subscribeOn(Scheduler scheduler) {
   ObjectHelper.requireNonNull(scheduler, "scheduler is null");
   return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}

scheduler是什么暂时不考虑,功能上它是一个管理线程的模块。这里是根据被观察者1和 Schedulers.io生成一个新的对象ObservableSubscribeOn(被观察者2)并返回。

final Scheduler scheduler;
public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
   super(source);
   this.scheduler = scheduler;
}

被观察者2为持有被观察者1和Schedulers.io的对象,持有被观察者1的对象为source。

创建被观察者3

下面开始调用observeOn方法:

public final Observable<T> observeOn(Scheduler scheduler) {
     return observeOn(scheduler, false, bufferSize());
}

添加两个参数继续传递:

public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
   return RxJavaPlugins.onAssembly(new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize));
}

同样是根据被观察者3和AndroidSchedulers.mainThread()以及另外两个参数生成一个新的对象ObservableObserveOn(被观察者3)并返回。

final Scheduler scheduler;
    final boolean delayError;
    final int bufferSize;
    public ObservableObserveOn(ObservableSource<T> source, Scheduler scheduler, boolean delayError, int bufferSize) {
        super(source);
        this.scheduler = scheduler;
        this.delayError = delayError;
        this.bufferSize = bufferSize;
}

被观察者3是一个持有被观察者2和AndroidSchedulers.mainThread(),以及另外两个引用的对象,持有被观察者++的对象为source。

下面看蓝线,蓝线是创建观察者之后关联到被观察者的过程。

1. 首先创建了观察者new Observer();

然后由被观察者3调用subscribe方法,参数为观察者。

public final void subscribe(Observer<? super T> observer) {
        ...
		subscribeActual(observer);
        ...
}

2. 创建worker和观察者1

重点看这一句代码就可以,因为是被观察者3调用subscribeActual,所以找到被观察者3中的subscribeActual方法。

protected void subscribeActual(Observer<? super T> observer) {
    if (scheduler instanceof TrampolineScheduler) {
        source.subscribe(observer);
    } else {
        Scheduler.Worker w = scheduler.createWorker();
		source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
    }
}

重点看else里面,scheduler为AndroidSchedulers.mainThread(),创建了一个worker对象,通过源码可以看出它是一个管理任务状态的类,此处暂不考虑。
然后根据观察者和worker来创建一个新的对象ObserveOnObserver(观察者1)。

3. 创建观察者2

然后source(被观察者2)调用subscribe,参数为观察者1。
同样的又关联到被观察者2的subscribeActual方法。

public void subscribeActual(final Observer<? super T> observer) {
    final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(observer);
    observer.onSubscribe(parent);
    parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}

可见,里面创建了SubscribeOnObserver对象(观察者2)该方法中主要管理Disposable生命周期。然后调用
onSubscribe,让观察者2和观察者1有所关联。最后一个是观察者2设置管理被观察者线程的代码,SubscribeTask中启动了异步执行被观察者1的subscribeActual。

4. 创建Emitter管理观察者和被观察者之间的连通。

protected void subscribeActual(Observer<? super T> observer) {
   CreateEmitter<T> parent = new CreateEmitter<T>(observer);
   observer.onSubscribe(parent);
   try {
       source.subscribe(parent);
   } catch (Throwable ex) {
       Exceptions.throwIfFatal(ex);
       parent.onError(ex);
   }
}

该方法中新建了一个CreateEmitter对象,此对象主要作用是使做消息发送,这个对象持有了观察者++的调用。并且调用了观察者的subscribe方法,最终指向:

@Override
public void subscribe(ObservableEmitter<String> emitter) {
     boolean isMain = (Looper.myLooper() == Looper.getMainLooper());
     Log.w("打印","create是否为主线程:"+String.valueOf(isMain));
     emitter.onNext("Hello World");
}

最后看绿线部分:

从emitter.onNext(“Hello World”)开始,调用了CreateEmitter的onnext方法。

public void onNext(T t) {
    ...
    if (!isDisposed()) {
        observer.onNext(t);
    }
}

由于CreateEmitter绑定的是观察者++,那么看观察者++的on next方法。

@Override
public void onNext(T t) {
    downstream.onNext(t);
}

再调用观察者+的on next方法。

@Override
public void onNext(T t) {
    ...
    schedule();
    ...
}
void schedule() {
   if (getAndIncrement() == 0) {
         worker.schedule(this);
   }
}

上面可见从该位置开始,worker.schedule(this)方法安排了worker的runable执行操作,而观察者+又与观察者和worker关联。

@Override
public void run() {
    ...
    drainNormal();
    ...
}
void drainNormal() {
    ...
    final SimpleQueue<T> q = queue;
    final Observer<? super T> a = downstream;
    for (;;) {
        ...
        for (;;) {
            ...
            T v;
			try {
                v = q.poll();
            } catch (Throwable ex) {
                ...
            }
            ...
            a.onNext(v);
         }
	...
}

异步执行之后,调用run方法,然后执行观察者的onNext方法,最终调用:

@Override
public void onNext(String s) {
    boolean isMain = (Looper.myLooper() == Looper.getMainLooper());
    Log.w("打印","onNext是否为主线程:"+String.valueOf(isMain));
    Log.w("打印","onNext结果:"+s);
}

到这里流程跑通了,中间也弄错了几次,最终调整到这个版,如果哪里写错了还希望大神指出,不胜感激!

猜你喜欢

转载自blog.csdn.net/yangshuaionline/article/details/86477855