Rxjava学习(一)简单分析Rxjava调用流程

2023-11-15

本篇以Rxjava最简短的调用流程为例来分析,下面是要分析的实例代码:

Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext("hahaha"); //执行二
                e.onComplete(); //执行四
                //e.tryOnError(new Throwable("error")); //执行四
            }
        }).subscribe(
                new Observer<String>() {
            @Override 
            public void onSubscribe(Disposable d) {
                disposable = d; //执行1
            }

            @Override
            public void onNext(String s) {
                  //执行三
            }

            @Override
            public void onError(Throwable e) {
                  //执行五
            }

            @Override
            public void onComplete() {
                  //执行五
            }
        });

无论是看官方文档还是自己打log验证,都会得出以上一二三四五的执行步骤(步骤四会在onError()和onComplete()选其一执行)。开始接触遇到这样的代码设计多多少少会感觉到有点反人类啊?当时我的第一感觉先不管设计合不合理,我就想知道它是怎么执行下来的?

很明显能发现这是链式调用,链式调用的核心就在于每个方法都返回相同的对象,当先省略掉其中的回调细节,我们可能会看的更清晰...

按照从左往右的顺序以及()优先级,代码的执行顺序如上图所示,接下来对每一步进行分析:

1、创建被观察者对象

Observable.create(
        //创建ObservableOnSubscribe接口的实例对象,
        new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext("hahaha");
                e.onComplete(); 
                //e.tryOnError(new Throwable("error")); //执行四
            }
        }
)
//Observable.java

//将上一步创建的ObservableOnSubscribe接口的实例对象传入
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
        ObjectHelper.requireNonNull(source, "source is null");
        //创建ObservableCreate对象
        return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
    }


//ObservableCreate.java
public final class ObservableCreate<T> extends Observable<T> {
    //将出入的ObservableOnSubscribe实例进行保存
    final ObservableOnSubscribe<T> source;

    public ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source;
    }
    ...
}
//RxJavaPlugins.java
//将上一步创建的ObservableCreate对象传入(ObservableCreate继承自Observable)
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
        //这部分是用于对Rxjava所有操作符的监听,本例中没有设置,属于干扰项不用看
        Function<? super Observable, ? extends Observable> f = onObservableAssembly;
        if (f != null) {
            return apply(f, source);
        }
        return source;
    }

到此被观察者对象创建完毕,即 ObservableCreate对象,它内部持有ObservableOnSubscribe对象。

2.创建观察者对象

new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                disposable = d;
            }

            @Override
            public void onNext(String s) {}

            @Override
            public void onError(Throwable e) {}

            @Override
            public void onComplete() {}
        }

这一步比较简单,只是创建了一个Observer<T>接口对象。

3、执行subscribe(),将以上两者关联(订阅)

//Observerable.java
//将观察者对象传入
public final void subscribe(Observer<? super T> observer) {
        try {
            ...
            //此方法是抽象方法,我们创建的被观察者对象是ObservableCreate,所以到此类中找方法实现
            subscribeActual(observer);
            ...
        } catch (NullPointerException e) { // NOPMD} catch (Throwable e) {}}
}


//ObservableCreate.java
//传入观察者对象
protected void subscribeActual(Observer<? super T> observer) {
        //创建发射器,这里将观察者传入CreateEmitter的构造参数
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);
        //调用观察者的onSubscribe(),即开始所说的 --- 执行一
        observer.onSubscribe(parent);

        try {
            //source 是 ObservableOnSubscribe 对象,在此调用到 --- 执行二
            source.subscribe(parent);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }

回顾一下执行二处的代码:

Observable.create(new ObservableOnSubscribe<String>() {
                    @Override
                    public void subscribe(ObservableEmitter<String> e) throws Exception {
                        Log.e("aaaaa:", "subscribe()");
                        e.onNext("hahaha"); //执行二
                        e.onComplete();  //执行四
                        //e.tryOnError(new Throwable("error"));

                    }
})
//ObservableCreate.java ObservableCreate.CreateEmitter内部类
 public void onNext(T t) {
           
       if (!isDisposed()) {
            //observer为构造函数中传入的观察者对象
            observer.onNext(t); //这里调用到--- 执行三
        }
 }

到此被观察者中发射的onNext()事件流程执行完毕,然后继续看执行四处发射了onComplete()或onError()事件。

     //ObservableCreate.java  CreateEmitter内部类
        @Override
        public void onComplete() {
            if (!isDisposed()) {
                try {
                    //调用观察者的onComplete()
                    observer.onComplete();
                } finally {
                    dispose();
                }
            }
        }

到此,调用到执行五,整个调用流程执行完毕。 

总结:分析rxjava的调用流程,最重要的就是一定要弄清每个方法(或者说是操作符)传入的或涉及到的observable或observer对象的真实类型,rxjava中涉及很多重载和重写,看错对象的类型就会转晕在rxjava的源码中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Rxjava学习(一)简单分析Rxjava调用流程 的相关文章

  • Xamarin 分步向导 Android 视图

    我想在 Xamarin c 中构建一个 android 活动 用于逐步注册和 或信息 我怎样才能做这样的事情 谁能给我一个代码示例或其他东西 谢谢 基本上你需要使用一个名为 a 的元素ViewPager 并且每个页面都会不同Fragment
  • 通过代码在创建时突出显示 ListView 项目

    我想在创建 listView 时突出显示 ListView 的第一行 0 我尝试了不同的方法 就像您在注释代码中看到的那样 但没有任何效果 这很奇怪 因为 OnItemClickListener 中的突出显示工作正常 它通过 xml 选择器
  • 升级到最新支持库后Android JACK编译器错误

    Android Studio 2 2 3 Windows 10 64位 构建工具版本 25 Android Gradle插件版本2 2 3 升级到最新的支持库 从 23 4 0 到 25 1 0 并更改编译版本 从 23 到 25 后 我收
  • 嵌套 XML 布局文件

    android 有没有办法从另一个布局文件引用 xml 布局文件 为了更好地解释 我有一个名为layout1 xml 和layout2 xml 的布局文件 我可以从layout1 xml引用layout2 xml吗 用这个
  • 当我单击“完成”键时,Android OnEditorActionListener() actionId 给出 0

    我创建了一个键盘 当用户输入数字时 它会输入特定的 EditText 但是当用户单击Done关键 它没有去setOnEditorActionListener但它关闭了键盘 这是我的代码 final EditText txtQty new E
  • 写入 Android UI Automator 输出控制台

    我正在 Android UI Automator 上编写一个小包装器 通常我们可以在控制台看到测试用例的状态 我可以访问它并添加我自己的消息吗 我努力了System out println 但这没有用 有什么办法可以做到这一点吗 您可以使用
  • 如何在Android中的DataBinding的ViewModel类中获取R.string

    我目前正在使用databinding对于我的 Android 应用程序项目 我想设置error留言在我的CustomTextView from R string txtOldPassWordError并从另一个名为的类中进行设置ViewMo
  • Play 商店中的应用描述更新

    我想更新应用程序的描述以及 Play 商店上的屏幕截图 但应用程序保持相同 即相同的版本号 我不想发布新应用程序 因为应用程序中没有任何更改 这可能吗 谷歌也会要求更新应用程序吗 您可以更新描述 也可以更改屏幕截图 您的应用程序将保持不变
  • 什么是 Android 测试协调器?

    谷歌最近发布了Android测试支持库1 0 读完后overview https android developers googleblog com 2017 07 android testing support library 10 is
  • AndEngine MenuScene - 无法单击按钮

    我有一个关于 android 和 andengine 的小问题 这是我的主菜单的源代码 AbstractScene is extending Scene public class MainMenuScene extends Abstract
  • 如何在同一设备上运行的 Android 应用程序之间传输文件?

    我正在编写一个与 RESTful 服务交互的 Android 应用程序 该 Web 服务本质上是一个文件系统 并提供元数据以及对文件的 CRUD 访问 我的应用程序检索元数据 并通过ContentProvider 我需要添加与我的应用程序在
  • 活动加载缓慢

    我的应用程序中有大约 50 个活动 但其中一个活动非常慢 我的意思是当我按下按钮进入该活动时 需要很长时间 有时会出现黑屏 在该活动中 我有一个按钮 如果我单击该按钮 则需要很长时间才能执行 代码很轻 只有一个Button EditText
  • 了解应用程序在后台时何时收到 Firebase 消息

    我知道这个标题有同样的问题 但不幸的是它没有得到正确的回答 它被接受了 here https stackoverflow com questions 37711082 how to handle notification when app
  • 通过 Gradle 和 Android Studio 构建和运行应用程序比通过 Eclipse 慢

    我有一个多项目 10 个模块 每次构建大约需要 20 30 秒 当我在 Android Studio 中按 运行 时 每次都必须等待才能重建应用程序 这非常慢 是否可以在 Android Studio 中自动化构建过程 或者您对如何加快此过
  • 用于请求带有临时缓存的远程 Observable 的 RxJava 模式

    用例是这样的 我想暂时缓存最新发出的昂贵的Observable响应 但在它过期后 返回到昂贵的源Observable并再次缓存它 等等 一个非常基本的网络缓存场景 但我真的很难让它工作 private Observable
  • 调试android数据绑定?

    谁能告诉我如何调试或找到数据绑定生成的代码 从this https www youtube com watch v NBbeQMOcnZ0链接我发现它生成了所需的代码 我猜您正在寻找自动生成的绑定 java 文件 我也在寻找他们 最后我在这
  • Android 从通知刷新 Activity

    我有一个程序 我在其中调用通知 如果您将其下拉 该通知将启动一个新活动 mNotificationManager NotificationManager getSystemService ns int icon R drawable sta
  • 在数组列表中过滤 Filterable 不取消之前的过滤

    我看过过滤器方法文档 其中显示调用过滤器会取消所有先前未执行的过滤请求 并发布一个稍后将执行的新过滤请求 但我收到的实际回调有些不同 在我的实现中 它不会取消先前的过滤器请求并调用publishResults 最近一次搜索条件后的上一次搜索
  • 我想测量 ListView 的高度 (getHight() = 0)

    我无法自己决定任务将是问 我想测量 ListView 的高度 无法捕捉渲染 ListView 的时刻 rssListView getHight 0 public class RSSactivity extends Activity publ
  • 如何用LoaderManager自动重新查询

    我有一个应用程序显示来自 SQLite DB 的数据 并且数据不断变化 所以显然 我认为我应该使用 LoaderManager 来显示数据 我读过一些关于将 LoaderManager 与 SQLite 结合使用的内容 然后看到了亚历克斯

随机推荐

  • 2023年03月 C/C++(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

    C C 编程 1 8级 全部真题 点这里 第1题 数字字符求和 请编写一个程序实现以下功能 从一个字符串中 提取出所有的数字字符即0 9 并作为数求和 时间限制 1000 内存限制 65536 输入 一行字符串 长度不超过100 字符串中不
  • facebook网络架构学习总结(F4)

    1 简介 1 1 大规模快速演进 Facebook 的生产网络本身就是一个大型分布式系统 针对不同任务划分成不同层次并采 用不同的技术 a large distributed system with specialized tiers an
  • mysql中如何设置时区_如何设置MySQL的时区?

    我认为这可能是有用的 有三个位置可以在MySQL中设置时区 在 mysqld 部分中的 my cnf 文件中default time zone 00 00 global Timezone变量 若要查看它们设置为什么值 请执行以下操作 SEL
  • 如何为Kafka集群选择合适的Topic/Partitions数量

    这是许多kafka使用者经常会问到的一个问题 本文的目的是介绍与本问题相关的一些重要决策因素 并提供一些简单的计算公式 越多的分区可以提供更高的吞吐量 首先我们需要明白以下事实 在kafka中 单个patition是kafka并行操作的最小
  • 2023华为OD机试真题【最左侧冗余覆盖子串/滑动窗口】

    题目描述 给定两个字符串 s1 和 s2 和正整数k 其中 s1 长度为 n1 s2 长度为 n2 在s2中选一个子串 满足 1 该子串长度为n1 k 2 该子串中包含s1中全部字母 3 该子串每个字母出现次数不小于s1中对应的字母 我们称
  • Element-UI 前端UI 组件库

    目录 Element UI 前端UI 组件库 配置Element UI 组件库 通过 UI 界面方式实现 配置插件 遇到的问题 Element UI 前端UI 组件库 个人博客地址 Element UI 前端UI 组件库 配置Element
  • Java代码连接数据库

    一 JDBC 全称 Java database connectivity java连接数据库 使用 Java 代码去连接数据库 然后对数据库中的数据进行增删改查 加载驱动 首先导入mysql的jar包 1 在 src 文件夹下面新建一个 l
  • 最长上升子序列(C语言 动态规划)

    描述 一个数的序列bi 当b1 lt b2 lt lt bS的时候 我们称这个序列是上升的 对于给定的一个序列 a1 a2 aN 我们可以得到一些上升的子序列 ai1 ai2 aiK 这里1 i1 lt i2 lt lt iK N 比如 对
  • linux设备利用率,linux – 对dm设备100%利用率的影响

    我们这里有一台RHEL 5 6服务器 有4条到单个LUN的活动路径 我们怀疑它无法将管道中的足够的IO塞进到另一端的XIV mpath0 XXXXXXXXXXXXXXX dm 9 IBM 2810XIV size 1 6T features
  • WARN Received a PartitionLeaderEpoch assignment for an epoch < latestEpoch

    Topic 处于 under replicated 状态 server log 充满 2020 11 30 19 00 00 006 WARN Received a PartitionLeaderEpoch assignment for a
  • MySQL---创建表和连表、分组、排序等操作

    首先这里有两张表做测试用 代码均在命令提示符终端完成 创建部门表 create table department table department id int auto increment primary key department v
  • TCP三次握手如果使用二次握手代替则会出现的问题

    简述 第一次握手 发送SYN报文 传达信息 你好 我想建立连接 第二次握手 回传SYN ACK报文 传达信息 好的 可以建立链接 第三次握手 回传ACK报文 传到信息 好的 我知道了 那我们连接 然后就建立连接了 在发送报文之前各方都要确认
  • Java基础——Math类、Random类、System类

    目录 1 Math类 2 Random类 3 System类 1 Math类 Math 类包含用于执行基本数学运算的方法 如初等指数 对数 平方根和三角函数 成员变量 public static final double E 自然底数 pu
  • java设计模式——代理模式(Proxy Pattern)

    概述 在某些情况下 一个客户不想或者不能直接引用一个对 象 此时可以通过一个称之为 代理 的第三者来实现 间接引用 代理对象可以在客户端和目标对象之间起到 中介的作用 并且可以通过代理对象去掉客户不能看到 的内容和服务或者添加客户需要的额外
  • 在vscode中创建vue自定义模板

    首先找到用户代码片段的位置 https img blog csdnimg cn 20201105094443610 png pic center 在输入框中输入vue 然后选择vue json或vue 打开之后是这样的 这些注释就是介绍怎么
  • SQL拼接存在的误区

    这两天修复一个SQL拼接的问题 给自己挖了个坑 对于指定的字符串作为查询条件时 当在SQL语句中使用单引号包裹查询条件时 需要注意以下几点 1 SQL注入攻击 如果接受外部输入的值直接拼接到SQL语句中 在查询条件中包含特殊字符如单引号或双
  • Java内部类总结

    Java内部类其实在J2EE编程中使用较少 不过在窗口应用编程中特别常见 主要用来事件的处理 其实 做非GUI编程 内部类完全可以不用 内部类的声明 访问控制等于外部类有所不同 要灵活使用内部类来编写程序 还是有相当难度的 Java发明了这
  • Web后台快速开发框架

    Web后台快速开发框架 Coldairarrow 目录 目录 第1章 目录 1 第2章 简介 3 第3章 基础准备 4 3 1 开发环境要求 4 3 2 基础数据库构建 4 3 3 运行 5 第4章 详细教程 6 4 1 代码架构 6 4
  • PC: 市场寒冬剖析

    市场调研机构Canalys数据显示 今年一季度 中国市场整体PC出货量同比下降24 至890万台 已是连续第五个季度下跌 今年截至618结束 都没有一家主要的PC厂商愿意发战报 PC市场怎样走出寒冬 谈谈你的理解和看法 PC 一 2022年
  • Rxjava学习(一)简单分析Rxjava调用流程

    本篇以Rxjava最简短的调用流程为例来分析 下面是要分析的实例代码 Observable create new ObservableOnSubscribe