RxJava/RxAndroid 详解——从基础到实现原理

RxJava/RxAndroid 详解——从基础到实现原理

RxJava的github地址:https://github.com/ReactiveX/RxJava
RxAndroid的github地址:https://github.com/ReactiveX/RxAndroid


提示:先别急着看github,我们先来认识RxJava和RxAndroid,从基本的使用学起。


前言

提示:以下是本篇文章正文内容,下面案例可供参考

一、RxJava是什么?

RxJava官方介绍: RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs by using observable sequences. It extends the observer pattern to support sequences of data/events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety and concurrent data structures. 1、Rx(Reactive Extensions)是一个库,用来处理【事件】和【异步】任务,在很多语言上都有实现,RxJava是Rx在Java上的实现。简单来说,RxJava就是处理异步的一个库,最基本是基于观察者模式来实现的。通过Obserable和Observer的机制,实现所谓响应式的编程体验。它扩展了观察者模式以支持数据/事件序列,并添加了运算符,使您可以声明性地将序列组合在一起,同时抽象化了对低级线程,同步,线程安全和并发数据结构等问题的关注。 2、RxAndroid是基于RxJava适用于Android的封装;官方给的这句大概会让你明白适配封装了啥:More specifically, it provides a Scheduler that schedules on the main thread or any given Looper.

二、概念

1.Observable 被观察者 ,事件源。是一个抽象类。
------ 1.1 ObservableEmitter 发射器;
2.Observer 观察者,事件接收处理。是一个接口。
3.subscribe 订阅,把被观察者和观察者关联起来。

先看下面RxJavaAndroid .java就好理解了这几个概念了。

三、基础使用

1.集成依赖

build.gradle中dependencies 下依赖;代码如下(示例):

dependencies {
    implementation "io.reactivex.rxjava3:rxjava:3.0.12"
    implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
}

2.用法及分析

/**
 *   注意别导错包。
 */
public class RxJavaAndroid {

    public static void main(String[] args) {
        doRxJava();
    }
    private static void doRxJava() {

        //通过 Observable.create 创建被观察者,Observable是一个抽象类
        Observable<String> observable = Observable.create(
                new ObservableOnSubscribe<String>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
                        //发射器发送消息
                        emitter.onNext("hello world");
                        //通过发射器发射异常
                        //emitter.onError(new Throwable("模拟一个异常"));
                        //发射完成
                        emitter.onComplete();
                    }
                }
        );
        
 		//通过 new Observer 创建观察者;Observer是一个 interface
        Observer<String> observer = new Observer<String>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                //第一个执行的方法
                System.out.println("onSubscribe");
            }

            @Override
            public void onNext(@NonNull String s) {
                System.out.println("onNext>>>" + s);
            }
                @Override
            public void onError(@NonNull Throwable e) {
                System.out.println("onError>>>" + e.getMessage());
            }

            @Override
            public void onComplete() {
                System.out.println("onComplete");
            }
        };
        
        //通过被观察者 Observable 的 subscribe (订阅) 绑定观察者 Observer
        observable.subscribe(observer);
    }

}

代码执行结果如下:
在这里插入图片描述

查看Observable源码

Observable 是数据的上游,事件源,即事件生产者。

	//一:接看代码 Observable.create()方法
    public static <T> Observable<T> create(@NonNull ObservableOnSubscribe<T> source) {
    	//ObservableOnSubscribe是一个只有subscribe方法的接口
        Objects.requireNonNull(source, "source is null");//判空
        return RxJavaPlugins.onAssembly(new ObservableCreate<>(source));
    }

	//二:继续向下看,进入RxJavaPlugins.onAssembly方法
	/**
     * Calls the associated hook function.
     * @param <T> the value type
     * @param source the hook's input value
     * @return the value returned by the hook
     */
	 @NonNull
    public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
        Function<? super Observable, ? extends Observable> f = onObservableAssembly;
        if (f != null) {
            return apply(f, source);
        }
        return source;
    }
//源码注释有介绍,Calls the associated hook function. hook java反射、钩子。底层管用黑科技。
//apply(f, source)的返回值依旧是Observable,里面不过多探究。

综上我们能发现
Observable.create(new ObservableOnSubscribe() { })
相当于
new ObservableCreate(new ObservableOnSubscribe() { }))
总结:事件的源就是 new ObservableCreate()对象,将 ObservableOnSubscribe 作为参数传递给 ObservableCreate 的构造函数。

查看Observer 源码

Observer 是数据的下游,即事件消费者。Observer 是个 interface。
查看源码,只有如下几个方法

  void onSubscribe(@NonNull Disposable d);
  void onNext(@NonNull T t);
  void onError(@NonNull Throwable e);
  void onComplete();

查看observable.subscribe 源码

  public final void subscribe(@NonNull Observer<? super T> observer) {
        Objects.requireNonNull(observer, "observer is null"); //判空
        try {
            observer = RxJavaPlugins.onSubscribe(this, observer);//通过hook返回observer

 			 Objects.requireNonNull(observer, "The RxJavaPlugins.onSubscribe hook returned a null Observer. Please change the handler provided to RxJavaPlugins.setOnObservableSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins");

            subscribeActual(observer);//核心、真正实现订阅的方法,仔细看subscribeActual是一个抽象方法,所以我们需要去Observable的实现类ObservableCreate中去查看
        } catch (NullPointerException e) { // NOPMD
            throw e;
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);
            // can't call onError because no way to know if a Disposable has been set or not
            // can't call onSubscribe because the call might have set a Subscription already
            RxJavaPlugins.onError(e);

            NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
            npe.initCause(e);
            throw npe;
        }

ObservableCreate类中发现

  @Override
    protected void subscribeActual(Observer<? super T> observer) {
   
        CreateEmitter<T> parent = new CreateEmitter<>(observer); //创建发射器,并把观察者当参数传递给发射器
        observer.onSubscribe(parent);//直接回调了observer的onSubscribe方法

        try {
            source.subscribe(parent);//source为Observable,事件源
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }

由上述源码可以看到,在ObservableCreate类的subscribeActual方法下,调用了Observer(观察者即事件接收者)的onSubscribe,并把observer对象当做参数专递给了发射器CreateEmitter;同时将发射器CreateEmitter传递给了事件源。因此可以得出结论:
只有当 observable.subscribe(observer);时,发射器才会被创建,Observer才会被绑定onSubscribe; Observable的subscribe方法才会执行发射事件和数据;此时Observable和Observer的方法和回调都已经准备就绪,只待发送与接收。换言之,事件流是在订阅后才产生的。而 observable 被创建出来时并不生产事件,同时也不发射事件。

ObservableEmitter发射器是如何发生的呢?

在这里插入图片描述CreateEmitter parent = new CreateEmitter<>(observer);
CreateEmitter实现了ObservableEmitter,同时ObservableEmitter继承自Emitter,CreateEmitter 还实现了 Disposable 接口,这个 disposable 接口是用来判断是否中断事件发射的。
CreateEmitter的主要方法如下

  public void onNext(T t) {}
  public void onError(Throwable t) {}
  public boolean tryOnError(Throwable t) {}
  public void onComplete() {}

前面我们说了 observer是个接口,与 observer的方法神似,几乎一一对应。
然后我们来分析一下CreateEmitter主要方法内都做了什么。

   @Override
        public void onNext(T t) {
            if (t == null) {
                onError(ExceptionHelper.createNullPointerException("onNext called with a null value."));
                return;
            }
            if (!isDisposed()) {	//判断是否丢弃
                observer.onNext(t);	//调用Emitter的onNext,它会直接调用observer的 onNext
            }
        }
        @Override
        public void onError(Throwable t) {
            if (!tryOnError(t)) {
                RxJavaPlugins.onError(t);  //调用 Emitter 的 onError,它会直接调用 observer 的 onError
            }
        }
         @Override
        public boolean tryOnError(Throwable t) {
            if (t == null) {
                t = ExceptionHelper.createNullPointerException("onError called with a null Throwable.");
            }
            if (!isDisposed()) {
                try {
                    observer.onError(t);
                } finally {
                    dispose(); //执行完中断发射
                }
                return true;
            }
            return false;
        }
   		@Override
        public void onComplete() {
            if (!isDisposed()) { 		/判断是否丢弃
                try {
                    observer.onComplete();//调用Emitter的onComplete,它会直接调用observer的 onComplete
                } finally {
                    dispose(); //执行完中断发射
                }
            }
        }

CreateEmitter 的 onError 和 onComplete 方法任何一个执行完都会执行 dispose()中断事件
发射,所以 observer 中的 onError 和 onComplete 也只能有一个被执行。

结合以上,我们知道了,当订阅成功后,数据 源ObservableOnSubscribe 开始生产事件 , 调用 Emitter 的 的 onNext ,onComplete 向下游发射事件,Emitter 包含了 observer 的引用,又调用了 observer onNext ,onComplete ,这样下 游observer 就接收到了上游发射的数据。

2.总结Rxjava 的流程

1.Observable.create 创建事件源,但并不生产也不发射事件。 2.实现 observer 接口,但此时没有也无法接受到任何发射来的事件。 3.订阅 observable.subscribe(observer), , 此时会调用具体 Observable 的实现类中的 subscribeActual 方法, 此时会才会真正触发事件源生产事件,事件源生产出来的事件通过 Emitter 的 的 onNext ,onError ,onComplete 发射给 observer 对应的方法由下游 observer 消费掉。从而完成整个事件流的处理。 4.observer 中的 onSubscribe 在订阅时即被调用,并传回了 Disposable, observer 中可以利用 Disposable 来随时中断事件流的发射。

四、RxJava 的线程调度机制

提示:这里对文章进行总结:

前面是为了更直观的分析代码才拆分开写的。现在我们用rxjava的Builder建造者模式来书写代码。

  private static void doWork() {

        Observable
                .create(new ObservableOnSubscribe<String>() {
                    @Override
                     public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
                        System.out.println("subscribe>>> thread name [" + Thread.currentThread().getName() + "]");
                        emitter.onNext("轻轻地我走了");
                    }
                })
                //.subscribeOn(Schedulers.io()) //先注释掉
  				.subscribe(new Observer<String>() {

                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@NonNull String s) {
                        System.out.println("onNext>>>thread name [" + Thread.currentThread().getName() + "]----" + s);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {

                    }
                      @Override
                    public void onComplete() {

                    }
                });
                }

执行结果肯定都是在main线程中,rxjava默认主线程。如下图:
在这里插入图片描述
当我们把.subscribeOn(Schedulers.io()) 代码行释放注释,再执行代码。执行结果如下图:
在这里插入图片描述
rxjava是通过 subscribeOn()来调度线程的

我们来看看 rxjava 是怎么完成这个线程调度的?

接着上面subscribeOn(Schedulers.io())查看源码:

	//1. Schedulers类
    @NonNull
    public static Scheduler io() {
        return RxJavaPlugins.onIoScheduler(IO); //进入了RxJavaPlugins
    }

	//2.RxJavaPlugins类
    /**
     * Calls the associated hook function.
     * @param defaultScheduler the hook's input value
     * @return the value returned by the hook
     */
    @NonNull
    public static Scheduler onIoScheduler(@NonNull Scheduler defaultScheduler) {
    //有是 调用  hook 函数(方法).
        Function<? super Scheduler, ? extends Scheduler> f = onIoHandler;
        if (f == null) {
            return defaultScheduler;
        }
        return apply(f, defaultScheduler);
    }
	//3.Schedulers类中
	  IO = RxJavaPlugins.initIoScheduler(new IOTask());  //IO为IOTask的实例
	
	//4.Schedulers类中
	    static final class IOTask implements Supplier<Scheduler> {
        @Override
        public Scheduler get() {
            return IoHolder.DEFAULT; // IOTask 为 IoHolder.DEFAULT 返回值
        }
    }
    
	//5.Schedulers类中
	    static final class IoHolder {
        static final Scheduler DEFAULT = new IoScheduler(); //DEFAULT  为IoScheduler实例
    }
    
	//6.IoScheduler类中
    public IoScheduler() {
        this(WORKER_THREAD_FACTORY);  // IoScheduler实例是这个常量
    }
    
    //7。IoScheduler类中   代码量过于庞大,这里只提取了关键代码行
     static final RxThreadFactory WORKER_THREAD_FACTORY;  //是 RxThreadFactory 
     WORKER_THREAD_FACTORY = new RxThreadFactory(WORKER_THREAD_NAME_PREFIX, priority);
       
     private static final String WORKER_THREAD_NAME_PREFIX = "RxCachedThreadScheduler";  //WORKER_THREAD_NAME_PREFIX 这是IO的默认线程名前缀
           
	// 8.RxThreadFactory 类
	/**
	 * A ThreadFactory that counts how many threads have been created and given a prefix,
	 * sets the created Thread's name to {@code prefix-count}.
	 */
	public final class RxThreadFactory extends AtomicLong implements ThreadFactory {  //注释已经说明RxThreadFactory 是创建线程的工厂类
	······
	}
	
	//9.IoScheduler 是个创建和缓存线程池
		/**
	 * Scheduler that creates and caches a set of thread pools and reuses them if possible.
	 */
	public final class IoScheduler extends Scheduler {······}

在此就不再继续刨根问底了,我们知道RxThreadFactory是用来创建线程的类。IoScheduler 创建和缓存线程池;大概就明白rxjava是通过 Scheduler (调度器)调度这些线程的;

那么具体是怎么实现调度的呢? 通过IoScheduler类,我们可以明白Scheduler 是如何创建IO线程的。

 public IoScheduler() {
        this(WORKER_THREAD_FACTORY);
    }

    /**
     * Constructs an IoScheduler with the given thread factory and starts the pool of workers.
     * @param threadFactory thread factory to use for creating worker threads. Note that this takes precedence over any
     *                      system properties for configuring new thread creation. Cannot be null.
     */
 public IoScheduler(ThreadFactory threadFactory) {
        this.threadFactory = threadFactory;
        this.pool = new AtomicReference<>(NONE);
        start();
    }

    @Override
    public void start() {
        CachedWorkerPool update = new CachedWorkerPool(KEEP_ALIVE_TIME, KEEP_ALIVE_UNIT, threadFactory);
        if (!pool.compareAndSet(NONE, update)) {
            update.shutdown();
        }
    }
  @Override
    public void shutdown() {
        CachedWorkerPool curr = pool.getAndSet(NONE);
        if (curr != NONE) {
            curr.shutdown();
        }
    }

    @NonNull
    @Override
    public Worker createWorker() {
        return new EventLoopWorker(pool.get());
    }
 	public int size() {
        return pool.get().allWorkers.size();
    }

    static final class EventLoopWorker extends Scheduler.Worker implements Runnable {
        private final CompositeDisposable tasks;
        private final CachedWorkerPool pool;
        private final ThreadWorker threadWorker;

        final AtomicBoolean once = new AtomicBoolean();
        
    EventLoopWorker(CachedWorkerPool pool) {
            this.pool = pool;
            this.tasks = new CompositeDisposable();
            this.threadWorker = pool.get();
        }

        @Override
        public void dispose() {
            if (once.compareAndSet(false, true)) {
                tasks.dispose();

                if (USE_SCHEDULED_RELEASE) {
                    threadWorker.scheduleActual(this, 0, TimeUnit.NANOSECONDS, null);
                } else {
                    // releasing the pool should be the last action
                    pool.release(threadWorker);
                }
            }
        }

        @Override
        public void run() {
            pool.release(threadWorker);
        }
  		@Override
        public boolean isDisposed() {
            return once.get();
        }

        @NonNull
        @Override
        public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
            if (tasks.isDisposed()) {
                // don't schedule, we are unsubscribed
                return EmptyDisposable.INSTANCE;
            }

            return threadWorker.scheduleActual(action, delayTime, unit, tasks);
        }
    }

通过上述代码分析, new IoScheduler()后,会创建new RxThreadFactory(WORKER_THREAD_NAME_PREFIX, priority)线程工厂类,然后执行 start()方法,创建 CachedWorkerPool 线程池,进行了一系列初始化配置和准备工作,但是并没有调度线程。所以 Schedulers.io()相当于只做了线程调度的前期准备。

我们再回到subscribeOn()方法。关键代码如下:

    @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.CUSTOM)
    @NonNull
    public final Observable<T> subscribeOn(@NonNull Scheduler scheduler) {
        Objects.requireNonNull(scheduler, "scheduler is null"); 
        // RxJavaPlugins.onAssembly 又是调用hook,关键之处是new ObservableSubscribeOn
        return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<>(this, scheduler));  
    }

很熟悉的代码 RxJavaPlugins.onAssembly,前面已经分析过这个方法,就是个 hook function, 等价于直接 return new ObservableSubscribeOn(this, scheduler);, 现在知道了这里的 scheduler 其实就是 IoScheduler。跟踪代码进入 ObservableSubscribeOn,可以看到这个 ObservableSubscribeOn 继承自 Observable,并且扩展了一些属性,增加了scheduler。我们已经知道了 Observable.subscribe()方法最终都是调用了对应的实现类的subscribeActual 方法。我们重点分析下 subscribeActual:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值