美文网首页
RxJava 消息订阅和线程切换的源码分析

RxJava 消息订阅和线程切换的源码分析

作者: LLhon | 来源:发表于2019-11-29 23:40 被阅读0次

    一、前言

    这里就不详细介绍怎么使用 RxJava 了,没用过的自行去 github 瞅瞅 >>>>> 地址
    本文源码基于 rxjava:2.2.15

    二、RxJava 的订阅流程

    咱们先来看个栗子:

            //步骤一:创建被观察者Observable,定义要发送的事件
            Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
                @Override public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                    emitter.onNext("0");
                    emitter.onNext("1");
                    emitter.onNext("2");
                    emitter.onComplete();
                }
            });
            //步骤二:创建观察者Observer,接收事件并作处理
            Observer<String> observer = new Observer<String>() {
                @Override public void onSubscribe(Disposable d) {
                    Log.d("RxJava", "onSubscribe");
                }
    
                @Override public void onNext(String s) {
                    Log.d("RxJava", "onNext: " + s);
                }
    
                @Override public void onError(Throwable e) {
                    Log.d("RxJava", "onError");
                }
    
                @Override public void onComplete() {
                    Log.d("RxJava", "onComplete");
                }
            };
            //步骤三:观察者订阅被观察者
            observable.subscribe(observer);
    

    输出结果:

    onSubscribe
    onNext: 0
    onNext: 1
    onNext: 2
    onComplete
    

    这里存在这么几个角色,被观察者(Observable)、观察者(Observer)、事件(Event)、订阅(Subscribe)。被观察者是负责生产事件的,观察者是负责接收事件并作处理,事件是被观察者和观察者的消息载体,也就是栗子中的 "0"、"1"、"2",订阅是连接被观察者和观察者。

    1、创建被观察者过程

    首先咱们来瞅瞅 Observable 的 create() 方法里面到底都干了什么事情

    1.1、Observable 类的 create()
    public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
        ObjectHelper.requireNonNull(source, "source is null"); //这里就是一个判空处理
        return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
    }
    

    可以看到其实这里就是先创建了一个 ObservableCreate 对象,同时把我们定义好的 ObservableOnSubscribe 对象作为参数传入进去,最后调用了 RxJavaPlugins.onAssembly() 方法。

    咱们先看看这个 ObservableCreate 类

    1.2、ObservableCreate 类
    public final class ObservableCreate<T> extends Observable<T> {
        final ObservableOnSubscribe<T> source;
    
        public ObservableCreate(ObservableOnSubscribe<T> source) {
            this.source = source;
        }
        // 省略无关代码...
    }
    

    可以看到 ObservableCreate 类是继承自 Observable 抽象类的, 然后把咱们传入的 ObservableOnSubscribe 对象存储了起来。

    再看下这个方法 RxJavaPlugins.onAssembly()

    1.3、RxJavaPlugins.onAssembly()
    public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
            // 省略无关代码...
            return source;
        }
    

    最终仅仅是把我们 new 出的 ObservableCreate 对象给返回来了。

    1.4、小结

    所以 Observable.create() 方法仅仅是把我们定义好的 ObservableOnSubscribe 对象重新包装成了一个 ObservableCreate 对象。

    2、创建观察者过程

    Observer<String> observer = new Observer<String>() {
          @Override public void onSubscribe(Disposable d) {
                    Log.d("RxJava", "onSubscribe");
                }
    
                @Override public void onNext(String s) {
                    Log.d("RxJava", "onNext: " + s);
                }
    
                @Override public void onError(Throwable e) {
                    Log.d("RxJava", "onError");
                }
    
                @Override public void onComplete() {
                    Log.d("RxJava", "onComplete");
                }
    };
    

    很简单,这里就是做了一个实现了 Observer 接口的匿名内部类实例化。

    3、订阅过程

    接下来我们一起看看订阅过程,点进去 observable.subscribe(observer);

    public final void subscribe(Observer<? super T> observer) {
        // 省略无关代码
        observer = RxJavaPlugins.onSubscribe(this, observer);
    
        subscribeActual(observer);
          
        // 省略无关代码
    }
    

    先分析第一行代码:

    3.1、RxJavaPlugins.onSubscribe()
    public static <T> Observer<? super T> onSubscribe(@NonNull Observable<T> source, @NonNull Observer<? super T> observer) {
            // 省略无关代码
            return observer;
        }
    

    跟之前代码一样,这里仅仅是把传入的 Observer 对象给返回来了

    再来分析第二行代码:

    3.2、Observable 类的 subscribeActual()
    protected abstract void subscribeActual(Observer<? super T> observer);
    

    很明显,这是抽象类 Observable 类的一个抽象方法,那它的具体实现在哪呢?其实它的具体实现类就是我们在前面创建被观察者时创建的 ObservableCreate 类,它就是 Observable 的子类,现在来看它的具体实现

    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 对象,第二步调用了 Observer 类的 onSubscribe() 方法,第三步调用了 ObservableOnSubscribe 类的 subscribe() 方法,其中这个 source 就是我们之前创建 ObservableCreate 对象传入进去的 ObservableOnSubscribe 对象。

    同样地,先看这个 CreateEmitter 类的创建过程:

    3.3、CreateEmitter 类
    static final class CreateEmitter<T>
        extends AtomicReference<Disposable>
        implements ObservableEmitter<T>, Disposable {
    
            private static final long serialVersionUID = -3434801548987643227L;
    
            final Observer<? super T> observer;
    
            CreateEmitter(Observer<? super T> observer) {
                this.observer = observer;
            }
    
            // 省略无关代码
        }
    

    CreateEmitter 类继承了原子引用类 AtomicReference,实现了 ObservableEmitter 和 Disposable 接口,把我们传入的 Observer 对象存储了起来,又是一个重新包装新对象的用法。

    3.4、Observer 类的 onSubscribe()
    observer.onSubscribe(parent);
    

    这个 onSubscribe() 回调的含义其实就是告诉观察者已经成功订阅了被观察者

    3.5、ObservableOnSubscribe 接口的 subscribe()
     source.subscribe(parent);
    

    这个 source 就是我们一开始传入的 ObservableOnSubscribe 对象,即这里会调用 ObservableOnSubscribe 的 subscribe() 方法,它的方法如下:

    Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
                @Override public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                    emitter.onNext("0");
                    emitter.onNext("1");
                    emitter.onNext("2");
                    emitter.onComplete();
                }
            });
    

    subscribe() 里的 onNext() 是用于将事件流发送出去,最后调用 onComplete() 方法代表完成了订阅过程。这里的 ObservableEmitter 接口其具体实现为 CreateEmitter 类,所以我们需要看看 CreateEmitter 类里的 onNext() 和 onComplete() 方法的实现

    static final class CreateEmitter<T>
        extends AtomicReference<Disposable>
        implements ObservableEmitter<T>, Disposable {
    
            @Override
            public void onNext(T t) {
                 // 省略无关代码...
                if (!isDisposed()) {
                    // 调用观察者的 onNext()
                    observer.onNext(t);
                }
            }
    
            // 省略无关代码...
    
            @Override
            public void onComplete() {
                if (!isDisposed()) {
                    try {
                        // 调用观察者的 onComplete()
                        observer.onComplete();
                    } finally {
                        dispose();
                    }
                }
            }
    
          // 省略无关代码...
    

    可以看到,最终就是会调用观察者的 onNext() 和 onComplete() 方法。至此,一个完整的消息订阅流程就完成了。

    三、RxJava 的线程切换

    先给出线程切换的栗子:

    Observable.create(new ObservableOnSubscribe<String>() {
                @Override public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                    emitter.onNext("0");
                    emitter.onNext("1");
                    emitter.onNext("2");
                    emitter.onComplete();
                }
            })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<String>() {
                    @Override public void onSubscribe(Disposable d) {
                        Log.d("RxJava", "onSubscribe");
                    }
    
                    @Override public void onNext(String s) {
                        Log.d("RxJava", "onNext: " + s);
                    }
    
                    @Override public void onError(Throwable e) {
                        Log.d("RxJava", "onError");
                    }
    
                    @Override public void onComplete() {
                        Log.d("RxJava", "onComplete");
                    }
            });
    

    四、总结

    相关文章

      网友评论

          本文标题:RxJava 消息订阅和线程切换的源码分析

          本文链接:https://www.haomeiwen.com/subject/qkdnwctx.html