RxJava 系列七:ObServer、Observable、subscribe源码分析

159 阅读5分钟

RxJava 系列七:源码分析

  • 本文概述:

    • 文章系统分析了:Observer 本质,具体业务实现位置;Observable创建过程、subscribe订阅流程,给出了具体的业务时序图,以及源码分析详细流程;结合之前的文章,总结了RxJava 设计模式与标准观察者设计模式的异同;

源码分析:Observer

  • 基础代码:

     /**
      * TODO RxJava的观察者模式
      * 1:Observer 源码看看
      * 2:Observable创建过程 源码分析
      * 3:subscribe订阅过程 源码分析
      */
     public class SourceActivity2 extends AppCompatActivity {
     ​
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
     ​
             // 结论: new ObservableCreate() {source == 自定义source}
             // 2:Observable创建过程 源码分析
             Observable.create(
     ​
                     // 自定义source
                     new ObservableOnSubscribe<String>() {
                         @Override
                         public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                             // 发射器.onNext
                             emitter.onNext("A");
                         }
             })
     ​
             // 3:subscribe订阅过程 源码分析
             // ObservableCreate. subscribe
             .subscribe(
                     // 自定义观察者
                     // 1:Observer 源码分析第一步
                     new Observer<String>() {
                         @Override
                         public void onSubscribe(Disposable d) {
     ​
                         }
     ​
                         @Override
                         public void onNext(String s) {
     ​
                         }
     ​
                         @Override
                         public void onError(Throwable e) {
     ​
                         }
     ​
                         @Override
                         public void onComplete() {
     ​
                         }
                     });
         }
     }
    
  • 进入Observer:源码入口

    image-20220628212031017

  • 源码展示:Observer

    • 这就是一个接口,接收的泛型作为分发的事件类型
     public interface Observer<T> {
     ​
         //订阅函数
         void onSubscribe(@NonNull Disposable d);
     ​
         //拿到上一个卡片的数据(事件)
         void onNext(@NonNull T t);
     ​
         //拿到上一个卡片的错误数据(事件)
         void onError(@NonNull Throwable e);
     ​
         //事件结束
         void onComplete();
     }
    
  • 真正的实现在业务代码中:

     new Observer<String>() {
         @Override
         public void onSubscribe(Disposable d) {
     ​
         }
     ​
         @Override
         public void onNext(String s) {
     ​
         }
     ​
         @Override
         public void onError(Throwable e) {
     ​
         }
     ​
         @Override
         public void onComplete() {
     ​
         }
     });
    

源码分析:Observable的创建过程

  • 关键代码:

     // 2:Observable创建过程 源码分析
     Observable.create(
         // 自定义source 指代下面的代码
         new ObservableOnSubscribe<String>() {
             @Override
             public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                 // 发射器.onNext
                 emitter.onNext("A");
             }
         })
    
  • 调用create操作符后发生了什么?

    • 流程:

      • 将source传给了.create

      • 自定义source判空

        • 空:抛出异常
         throw new NullPointerException(message);
        
      • 返回全局Hook

       return RxJavaPlugins.onAssembly
      
    • 关键代码:以自定义source为参数,创建一个与操作符对应的对象实例并保存

       //创建
       new ObservableCreate<T>(source)
       //保存位置:ObservableCreate.java
       public final class ObservableCreate<T> extends Observable<T> {
           final ObservableOnSubscribe<T> source;
       ​
           public ObservableCreate(ObservableOnSubscribe<T> source) {
               this.source = source;
           }  
      
     @CheckReturnValue
     @SchedulerSupport(SchedulerSupport.NONE)
     public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
         //自定义source判空
         ObjectHelper.requireNonNull(source, "source is null");
         
         return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
     }
    

最难的源码分析:subscribe订阅过程 源码分析

整体结构:U型结构

  • 实现:起点到终点再回到起点;且可以无数次使用卡片(拦截器)

  • 示意图:自定义版本

    RxJava简单订阅过程

  • 示意图:简化版

    img

  • 示意图:详细时序图

    RxJava时序图

RxJava 的观察者设计模式与标准观察者设计模式的区别

  • 概念性:

    • 标准:一个被观察者,多个观察者 且 当且仅当被观察者发生改变后才会通知观察者
    • RxJava:一个观察者(只有一个终点),多个被观察者(理论上有无限次卡片,卡片的本质就是Observable) 且 一订阅就会触发观察者,并不需要等待被观察者发生改变
  • 从模式上讲:RxJava 称为 发布 - 订阅模式更加贴切

    • 两个模式效果都一样,只是说结构上多了一个抽象层;但是少一个容器
  • 从执行流程上来看:

    • 标准(耦合度高):一个被观察者中存在一个容器存放多个观察者,当被观察改变时,去遍历容器,一次通知所有的观察者
    • RxJava :存在结构独立的被观察者 与 观察者,且在二者之间存在一个抽象层(发射器);

    • 耦合度更低(面向抽象层编程):被观察者改变(发布)时:被观察者.onNext() ---> 抽象层(发射器).onNext() ---> 观察者.onNext()

      • 面向抽象层的好处:RxJava 的精华

        • 发布时可以在抽象层后无限添加卡片,发射器--->卡片 ---> 观察者

        • 发射器是怎么干的:具体怎么干,不管(我只是面向于抽象层)

          • 内部做了封装包装一层后再去调用下面的onNext()

             @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);
                 }
             }
            

是谁调用的subscribe

  • 是操作符对象实例
.subscribe 相当于 ObservableCreate实例.subscribe

调用之后发生了什么?

  • 前置条件:将如下代码命名为自定义观察者

     // 自定义观察者
     new Observer<String>() {
         @Override
         public void onSubscribe(Disposable d) {
         }
         @Override
         public void onNext(String s) {
         }
         @Override
         public void onError(Throwable e) {
         }
         @Override
         public void onComplete() {
         }
     });
    
  • 将自定义观察者作为参数传入并校验(判空 )

    observer = RxJavaPlugins.onSubscribe(this, observer);
    
    ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
    
  • 调用 subscribeActual(observer):在操作符对象中重写并调用

    • 这是一个抽象函数,那么这个函数一定在其实现类中重写了(推断在ObservableCreate)

      • 抽象函数:

         protected abstract void subscribeActual(Observer<? super T> observer);
        
      • 验证推断:查看ObservableCreate

         public final class ObservableCreate<T> extends Observable<T> {
             ……
             //真的重写了,将自定义观察者作为参数传入
             @Override
             protected void subscribeActual(Observer<? super T> observer) {
                 ……
             }
        
  • ObservableCreate 中重写的 subscribeActual()

    • 实例化发射器,参数为自定义观察者
    • 触发业务代码订阅处的 onSubscribe
    • 调用业务代码中操作符后紧跟的 自定义 source
     @Override
     protected void subscribeActual(Observer<? super T> observer) {
         //将自定义观察者作为参数,实例化发射器
         CreateEmitter<T> parent = new CreateEmitter<T>(observer);
         //自定义观察者,立即调用业务代码中的 订阅处重写的 onSubscribe
         observer.onSubscribe(parent);
     ​
         try {
             //发射器作为实参,由自定义source触发,立即调用业务代码中操作符后紧跟的自定义source
             source.subscribe(parent);
         } catch (Throwable ex) {
             Exceptions.throwIfFatal(ex);
             parent.onError(ex);
         }
     }
    
    • 订阅处重写的onSubscribe

       .subscribe(
       ​
           new Observer<String>() {
               //就是这个函数
               @Override
               public void onSubscribe(Disposable d) {
                   
               }
      
    • 操作符后紧跟的自定义source

       Observable.create(
           new ObservableOnSubscribe<String>() {
               //就是调用额这个函数
               @Override
               public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                   // 发射器.onNext
                   emitter.onNext("A");
               }
           })