rxJava和rxAndroid源码解析系列一之链式调用Observable嵌套

后期项目需要用RxJava和Rxandroid框架,趁着闲暇时间,学习一下框架。就从简单的demo开始,窥探这个异步框架的冰山一角。(建议打开编译工具,边看文章边源码,因为逻辑有点绕)废话不多说,直接上代码。

另外说一下rxjava和rxandroid引用的版本

 implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
 implementation 'io.reactivex.rxjava2:rxjava:2.2.2'
package com.test.dxy;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;



import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        rxJavaInit();
    }

    private void rxJavaInit(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                Observable.create(new ObservableOnSubscribe() {//create创建产生的实例类型ObservableCreate
                    @Override
                    public void subscribe(ObservableEmitter emitter) throws Exception {
                        Log.i("MainActivity",Thread.currentThread().getId()+":"+Thread.currentThread().getName());
                        emitter.onNext("hello");
                        emitter.onNext("world");
                        emitter.onComplete();
                    }
                }).subscribeOn(Schedulers.newThread())//subscribeOn创建产生的实例类型ObservableSubscribeOn
                        .observeOn(AndroidSchedulers.mainThread()) //observeOn创建产生的实例类型ObservableObserveOn
                        .subscribe(new Observer() {
                            @Override
                            public void onSubscribe(Disposable d) {
                                Log.i("MainActivity","onSubscribe"+Thread.currentThread().getId()+":"+Thread.currentThread().getName());
                            }

                            @Override
                            public void onNext(String s) {
                                Log.i("MainActivity",Thread.currentThread().getId()+":"+Thread.currentThread().getName());
                                Log.i("MainActivity",s);
                            }
                            @Override
                            public void onError(Throwable e) {

                            }
                            @Override
                            public void onComplete() {
                                Log.i("MainActivity",Thread.currentThread().getId()+":"+Thread.currentThread().getName());
                                Log.i("MainActivity","onComplete");
                            }
                        });
            }
        }).start();
    }
}

                                                               <样例代码片段1>

把代码跑起来,下面是打印的日志信息

rxJava和rxAndroid源码解析系列一之链式调用Observable嵌套_第1张图片

从日志中可以看到Observer的onSubscribe(Disposable d)方法运行在一个线程中,而Observer的其他回调(onNext,onError,onComplete)运行在主线程中,ObservableOnSubscribe中的subscribe方法运行在另外一个线程中,和Observer的nSubscribe(Disposable d)方法的运行不在同一个线程,这个是怎么回事呢?这个线程间的切换是怎么完成的呢?又是怎么回调的呢?带着这些疑问去追踪一下源码,看一下框架的运行机制。怎么分析这份代码呢?这个框架代码都是链式的,那就一个节点一个节点的分析。

  (节点一)首先看一下第一个节点,也就是Observable.create(ObservableOnSubscribe source)这个方法。来看看源码做了什么

    @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    public static  Observable create(ObservableOnSubscribe source) {
        ObjectHelper.requireNonNull(source, "source is null");
        return RxJavaPlugins.onAssembly(new ObservableCreate(source));
    }

                                                                                             <源代码片段1>

可以看到该方法返回一个Observable的实例,这个实例是什么呢?看一下RxJavaPlugins类的onAssembly方法。

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @NonNull
    public static  Observable onAssembly(@NonNull Observable source) {
        //onObservableAssembly为null
        Function f = onObservableAssembly;
        if (f != null) {//这个if判断就会跳过
            return apply(f, source);
        }
        return source;//直接返回传入的参数Observable对象
    }

                                                                     <源代码片段2>

所以Observable.create(ObservableOnSubscribe source)返回的对象就是ObservableCreate的对象。ObservableCreate肯定是Observable的子类。

 

public final class ObservableCreate extends Observable {
    final ObservableOnSubscribe source;

    public ObservableCreate(ObservableOnSubscribe source) {
        this.source = source;
    }
  ...................省略
}

                                                                                      <源代码片段3>

好的,现在已经知道第一个节点Observable.create(ObservableOnSubscribe source)会返回一个ObservableCreate对象。ObservableCreate的source对象是谁呢?通过<源代码片段1>知道,是创建过来的,ObservableCreate.create调用的代码是


                Observable.create(new ObservableOnSubscribe() {//create创建产生的实例类型ObservableCreate
                    @Override
                    public void subscribe(ObservableEmitter emitter) throws Exception {
                        Log.i("MainActivity",Thread.currentThread().getId()+":"+Thread.currentThread().getName());
                        emitter.onNext("hello");
                        emitter.onNext("world");
                        emitter.onComplete();
                    }
                })

                                                                             <样例代码片段2>

 所以ObservableCreate的成员变量source是上面ObservableOnSubscribe的对象。

 

(节点二)接着看ObservableCreate.subscribeOn(Schedulers.newThread())这一个节点,这个方法是Observable的方法,所以ObservableCreate肯定也会继承这个方法,因为ObservableCreate是Observable的子类。那我们看看这个方法

    @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.CUSTOM)
    public final Observable subscribeOn(Scheduler scheduler) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");//判空操作
        return RxJavaPlugins.onAssembly(new ObservableSubscribeOn(this, scheduler));//主要看这个返回的对象
    }

                                                                                        <源代码片段4>

根据第一个节点的分析RxJavaPlugins.onAssembly方法会返回一个Observable,且就是传入的参数,所以返回的就是ObservableSubscribeOn对象,根据源码我们可以知道这个也是Observable的一个子类,不信,你往下看

public final class ObservableSubscribeOn extends AbstractObservableWithUpstream {
    final Scheduler scheduler;

    public ObservableSubscribeOn(ObservableSource source, Scheduler scheduler) {
        super(source);
        this.scheduler = scheduler;
    }
..................省略
}

                                                                                      <源代码片段5> 

ObservableSubscribeOn继承这个AbstractObservableWithUpstream类,好像不是阿,别急,那我们就看看这个类AbstractObservableWithUpstream。

abstract class AbstractObservableWithUpstream extends Observable implements HasUpstreamObservableSource {
......................省略
}

                                                                                    <源代码片段6> 

这回看到了吧,ObservableSubscribeOn间接继承这个类Observable。那ObservableSubscribeOn的成员变量source是谁呢?

根据 <源代码片段5> 可以知道这个是构造函数传递过来的。 根据 <源代码片段4>知道这个source就是这个this。谁调用了subscribeOn这个方法呢,当然是ObservableCreate的对象,所以这个source就是ObservableCreate的对象。

那ObservableSubscribeOn的成员变量scheduler是谁呢? 根据 以上调用构建知道scheduler是这个东东Schedulers.newThread()

 那就看看这个方法

    @NonNull
    public static Scheduler newThread() {
        return RxJavaPlugins.onNewThreadScheduler(NEW_THREAD);
    }

                                                                               <源代码片段7>  

 还在调用,那就继续跟踪

   @NonNull
    public static Scheduler onNewThreadScheduler(@NonNull Scheduler defaultScheduler) {
//onNewThreadHandler这里为null
        Function f = onNewThreadHandler;
        if (f == null) {
//直接返回传入的参数
            return defaultScheduler;
        }
        return apply(f, defaultScheduler);
    }

                                                                           <源代码片段8>  

 直接返回传入的参数那就是NEW_THREAD这个啦,NEW_THREAD是Schedulers的静态常量,赋值在静态代码块

    static {
        SINGLE = RxJavaPlugins.initSingleScheduler(new SingleTask());

        COMPUTATION = RxJavaPlugins.initComputationScheduler(new ComputationTask());

        IO = RxJavaPlugins.initIoScheduler(new IOTask());

        TRAMPOLINE = TrampolineScheduler.instance();
        
        NEW_THREAD = RxJavaPlugins.initNewThreadScheduler(new NewThreadTask());
    }

                                                                         <源代码片段9>  

 RxJavaPlugins.initNewThreadScheduler(new NewThreadTask())才是scheduler的值,继续往里面跟进

    @NonNull
    public static Scheduler initNewThreadScheduler(@NonNull Callable defaultScheduler) {
        ObjectHelper.requireNonNull(defaultScheduler, "Scheduler Callable can't be null");
//onInitNewThreadHandler这里为null
        Function, ? extends Scheduler> f = onInitNewThreadHandler;
        if (f == null) {
             //也就是把传入的参数new NewThreadTask()继续往里面传
            return callRequireNonNull(defaultScheduler);
        }
        return applyRequireNonNull(f, defaultScheduler);
    }

                                                                            <源代码片段10>  

 还是没有获取scheduler的值,继续跟踪

    @NonNull
// 传入的参数new NewThreadTask()
    static Scheduler callRequireNonNull(@NonNull Callable s) {
        try {
            return ObjectHelper.requireNonNull(s.call(), "Scheduler Callable result can't be null");
        } catch (Throwable ex) {
            throw ExceptionHelper.wrapOrThrow(ex);
        }
    }

                                                                          <源代码片段11>  

 看到希望了,ObjectHelper.requireNonNull(s.call(), "Scheduler Callable result can't be null");就把scheduler的值返回了,继续跟进

//new NewThreadTask().call()返回的就是object ,这个 object 就是scheduler啦
public static  T requireNonNull(T object, String message) {
        if (object == null) {//当然不为空了
            throw new NullPointerException(message);
        }
        return object;
    }

                                                                        <源代码片段12>  

 哦,scheduler原来是new NewThreadTask().call()返回的值,那就看看这个方法

    static final class NewThreadTask implements Callable {
        @Override
        public Scheduler call() throws Exception {
            return NewThreadHolder.DEFAULT;
        }
    }

                                                                     <源代码片段13>  

 原来是这个东东NewThreadHolder.DEFAULT,都跟到这里啦,那就看看喽,不然就白费力气啦

   static final class NewThreadHolder {
        static final Scheduler DEFAULT = new NewThreadScheduler();
    }

                                                                     <源代码片段14>  

 终于看到了,scheduler是NewThreadScheduler的实例对象。NewThreadScheduler是Scheduler的子类,嗯,明白!

 

(节点三)ObservableSubscribeOn.observeOn(AndroidSchedulers.mainThread())

  @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.CUSTOM)
    public final Observable observeOn(Scheduler scheduler) {
        return observeOn(scheduler, false, bufferSize());
    }

                                                                                <源代码片段15> 

看来还得往下看这个方法

    @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.CUSTOM)
    public final Observable observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        ObjectHelper.verifyPositive(bufferSize, "bufferSize");
        //根据节点一说的直接返回ObservableObserveOn类的对象
        return RxJavaPlugins.onAssembly(new ObservableObserveOn(this, scheduler, delayError, bufferSize));
    }

                                                                                  <源代码片段16> 

到这一步我们知道了,该节点会创建ObservableObserveOn对象。ObservableObserveOn也是AbstractObservableWithUpstream的子类,AbstractObservableWithUpstream类又是Observable的子类。

所以得出继承关系图

rxJava和rxAndroid源码解析系列一之链式调用Observable嵌套_第2张图片

                                      

那就看看ObservableObserveOn的构造方法

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

这个也有source和scheduler,这个真的要了解一下,不然就不紧扣主题了嘛?根据  <源代码片段16> ,知道this就是source,似曾相识的套路,不就是谁调用当前节点就是谁吗。搜嘎,ObservableSubscribeOn的实例对象就是这个source,那scheduler呢,我感觉这个也是和上面的一个套路吧,那就验证一下,这个想法啦。AndroidSchedulers.mainThread()就是scheduler阿,这个怎么产生的呢,继续 探索

   /** A {@link Scheduler} which executes actions on the Android main thread. */
    public static Scheduler mainThread() {
        return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
    }

                看到这里,心里特别happy,相同的套路,不想说了,上一下图,

    public static Scheduler onMainThreadScheduler(Scheduler scheduler) {
        if (scheduler == null) {
            throw new NullPointerException("scheduler == null");
        }
        Function f = onMainThreadHandler;
        if (f == null) {
            return scheduler;
        }
        return apply(f, scheduler);
    }

 

    private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(
            new Callable() {
                @Override public Scheduler call() throws Exception {
                    return MainHolder.DEFAULT;
                }
            });
    public static Scheduler initMainThreadScheduler(Callable scheduler) {
        if (scheduler == null) {
            throw new NullPointerException("scheduler == null");
        }
        Function, Scheduler> f = onInitMainThreadHandler;
        if (f == null) {
            return callRequireNonNull(scheduler);
        }
        return applyRequireNonNull(f, scheduler);
    }
    static Scheduler callRequireNonNull(Callable s) {
        try {
            Scheduler scheduler = s.call();
            if (scheduler == null) {
                throw new NullPointerException("Scheduler Callable returned null");
            }
            return scheduler;
        } catch (Throwable ex) {
            throw Exceptions.propagate(ex);
        }
    }
 private static final class MainHolder {
        static final Scheduler DEFAULT
            = new HandlerScheduler(new Handler(Looper.getMainLooper()), false);
    }

通过上面一系列追踪,知道scheduler就是HandlerScheduler,handler不就是主线程的handler嘛,搜嘎!

嗯,这个scheduler见了好几个,什么关系呢

rxJava和rxAndroid源码解析系列一之链式调用Observable嵌套_第3张图片

以上三个节点对象实例关系图

rxJava和rxAndroid源码解析系列一之链式调用Observable嵌套_第4张图片

总结:链式调用,在subscribe方法之前进行了observable的多次创建,且observable的source对象都是对之前的observable的引用。

注:本来打算一章结束的,谁知道内容有点多,就打算做个序列。那么晚了,睡觉,明天继续!

感觉还可以的朋友,如果有兴趣可以看下一篇rxJava和rxAndroid源码解析系列二之observer订阅

你可能感兴趣的:(android)