当前位置: 首页 > news >正文

RxJava学习记录

文章目录

  • 1. 总览
    • 1.1 基本原理
    • 1.2 导入包和依赖
  • 2. 操作符
    • 2.1 创建操作符
    • 2.2 转换操作符
    • 2.3 组合操作符
    • 2.4 功能操作符

1. 总览

1.1 基本原理

在这里插入图片描述
参考文献
在这里插入图片描述
构建流:每一步操作都会生成一个新的Observable节点(没错,包括ObserveOn和SubscribeOn线程变换操作),并将新生成的Observable返回,直到最后一步执行subscribe方法。编写Rxjava代码的过程其实就是构建一个一个Observable节点的过程
订阅流:从最后一个N5节点的订阅行为开始,依次执行前面各个节点真正的订阅方法。在每个节点的订阅方法中,都会生成一个新的Observer**,这个Observer会包含“下游”的Observer,这样当每个节点都执行完订阅(subscribeActual)后,也就生成了一串Observer,它们通过downstream,upstream引用连接
回调流: 当订阅流执行到最后,也就是第一个节点N0时,用onNext方法,两个作用,一个是把上个节点返回的数据进行一次map变换,另一个就是将map后的结果传递给下游。
小结:先从上到下把各个变换的Observable连成链(拼装流水线),然后在最后subscribe的时候,又从下到上通过每个Observable的OnSubscribe从最下的Subscriber对象开始连成链(流水线开始工作包装Subscriber),直到顶端,当顶端的Subscriber对象调用了onNext方法的时候,又从上往下调用Subscriber链的onNext(用户一层层拆开包装盒),里面执行了每个操作的变换逻辑。

1.2 导入包和依赖

implementation 'io.reactivex.rxjava2:rxjava:2.2.21'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'

2. 操作符

添加链接描述

2.1 创建操作符

  • Create
    private void test1() {//被观察者Observable;观察者Observer/消费者consumer;通过subsribe订阅Observable.create(new ObservableOnSubscribe<Object>() {@Overridepublic void subscribe(ObservableEmitter<Object> emitter) throws Exception {emitter.onNext("1");
//                emitter.onError(new Throwable("异常模拟"));emitter.onComplete();}}).subscribe(new Observer<Object>() {@Overridepublic void onSubscribe(Disposable d) {System.out.println("subscribe");}@Overridepublic void onNext(Object o) {System.out.println("onNext Observer " + o);}@Overridepublic void onError(Throwable e) {System.out.println("erro");}@Overridepublic void onComplete() {System.out.println("Complete Observer....");}});}private void test2() {Disposable d = Observable.create(new ObservableOnSubscribe<Object>() {@Overridepublic void subscribe(ObservableEmitter<Object> emitter) throws Exception {emitter.onNext("2");emitter.onError(new Throwable("模拟异常"));emitter.onComplete();}}).subscribe(new Consumer<Object>() {@Overridepublic void accept(Object o) throws Exception {System.out.println("Accept " + o);}}, new Consumer<Throwable>() {@Overridepublic void accept(Throwable throwable) throws Exception {System.out.println("Accept " + throwable);}});}

Observer:
适合需要完整事件处理的场景,包括处理数据、错误和完成信号。
提供了更灵活的事件处理能力,可以根据需求实现对错误和完成事件的响应。
Consumer:
适合简单的场景,只需处理每个发出的数据项,而不需要关心错误或完成事件。
简化了代码结构,特别是在处理简单流时,使用起来更为便捷和直观。

  • 其他
    just 10个发射源
    from 将一个Iterable、一个Future、 或者一个数组,内部通过代理的方式转换成一个Observable
    interval操作符 创建一个按固定时间间隔发射整数序列的Observable,这个序列为一个无限递增的整数序列
    range操作符 发射一个范围内的有序整数序列,并且我们可以指定范围的起始和长度
    repeat操作符 重复发射原始Observable的数据序列,这个序列或者是无限的,或者通过repeat(n)指定重复次数

2.2 转换操作符

map
将源Observable发送的数据转换为一个新的Observable对象

    private void test3(){Observable.just("111").map(new Function<String, Object>() {@Overridepublic Object apply(String s) throws Exception {return "my name is " + s;}}).subscribe(ob);}//subscribe
//onNext Observer my name is 111
//Complete Observer....

flatmap
添加链接描述
在这里插入图片描述
将一个发送事件的上游Observable变换为多个发送事件的Observables,然后将它们发射的事件合并后放进一个单独的Observable里(但是是无序的)

    private void test4(){Disposable ob = Observable.create(new ObservableOnSubscribe<Integer>() {@Overridepublic void subscribe(ObservableEmitter<Integer> emitter) throws Exception {emitter.onNext(1);emitter.onNext(2);emitter.onNext(3);}}).flatMap(new Function<Integer, ObservableSource<String>>() {@Overridepublic ObservableSource<String> apply(Integer o) throws Exception {final List<String> list = new ArrayList<>();for (int i = 0; i < 3; i++) {list.add("I am value " + o);}return Observable.fromIterable(list).delay(10, TimeUnit.MILLISECONDS);//为了无序 加了延迟}}).subscribe(new Consumer<String>() {@Overridepublic void accept(String o) throws Exception {System.out.println(o);}});}//出现的 1 2 3会随机出现

concatMap
concatMap操作符类似于flatMap操作符,不同的一点是它按次序连接。

2.3 组合操作符

concat
concatArray
合并多个对象,按照一定的顺序
在这里插入图片描述
merge
在这里插入图片描述

2.4 功能操作符

SubscribeOn 改变调用它之前代码的线程,只有第一次有效
ObserveOn 改变调用它之后代码的线程, 可以多次调用

        Observable.create(new ObservableOnSubscribe<Object>() {@Overridepublic void subscribe(ObservableEmitter<Object> emitter) throws Exception {Log.d(TAG,"加了subscribeOn和observeOn: " + Thread.currentThread().getName());emitter.onNext("1111");emitter.onNext("22222");emitter.onComplete();}}).subscribeOn(Schedulers.newThread()) //1 进行创建和发射在子线程.observeOn(AndroidSchedulers.mainThread())// 2 在主线程消费;由于程序是test里面执行,所以不是main线程;后续改成了main是一样的道理.subscribe(new Observer<Object>() {@Overridepublic void onSubscribe(Disposable d) {Log.d(TAG,"onSubscribe " + Thread.currentThread().getName());}@Overridepublic void onNext(Object o) {Log.d(TAG,"onNext " + Thread.currentThread().getName());}@Overridepublic void onError(Throwable e) {Log.d(TAG,"onError " + Thread.currentThread().getName());}@Overridepublic void onComplete() {Log.d(TAG,"onComplete " + Thread.currentThread().getName());}});}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
这一个onSubsribe 一直是在测试线程里


1. **Observable 的创建和订阅**:- 在 `subscribe()` 方法中,你创建了一个 `Observer` 对象,并将其订阅到了 `Observable` 对象上。2. **onSubscribe 方法执行**:- 当 `subscribe()` 方法被调用后,`Observer` 对象的 `onSubscribe` 方法会立即执行。这是因为 `onSubscribe` 是 `Observer` 接口的一部分,它负责接收 `Disposable` 对象,表示订阅关系,而不是响应数据流本身。3. **异步操作执行**:- 然后,`Observable` 中的异步操作开始执行。在你的例子中,通过 `Observable.create()` 创建了一个新的数据流,该数据流会在新线程(通过 `subscribeOn(Schedulers.newThread())` 指定的线程)中执行。这意味着 `Observable.create()` 中的代码块会在新线程中运行,而不会阻塞主线程。4. **数据流发射和消费**:- 在新线程中,`ObservableEmitter` 会发射数据项(通过 `emitter.onNext()` 发送数据)并在合适的时机调用 `onComplete()` 或者 `onError()`,表示数据流的结束。5. **observeOn 切换到主线程**:- 通过 `observeOn(AndroidSchedulers.mainThread())`,确保在数据流中的消费者部分(即 `Observer` 的 `onNext()`, `onError()`, `onComplete()` 方法)在主线程中执行。这个切换保证了在主线程更新UI或处理数据,从而避免了在主线程中执行耗时操作而导致的UI阻塞问题。

相关文章:

RxJava学习记录

文章目录 1. 总览1.1 基本原理1.2 导入包和依赖 2. 操作符2.1 创建操作符2.2 转换操作符2.3 组合操作符2.4 功能操作符 1. 总览 1.1 基本原理 参考文献 构建流&#xff1a;每一步操作都会生成一个新的Observable节点(没错&#xff0c;包括ObserveOn和SubscribeOn线程变换操作…...

Spring Boot Vue 毕设系统讲解 3

目录 项目配置类 项目中配置的相关代码 spring Boot 拦截器相关知识 一、基于URL实现的拦截器&#xff1a; 二、基于注解的拦截器 三、把拦截器添加到配置中&#xff0c;相当于SpringMVC时的配置文件干的事儿&#xff1a; 项目配置类 项目中配置的相关代码 首先定义项目认…...

Spring Boot对接大模型:实战价值与技巧

Spring Boot对接大模型&#xff1a;实战价值与技巧 随着大数据和人工智能技术的飞速发展&#xff0c;大模型&#xff08;Large-scale Models&#xff09;在各个行业中的应用越来越广泛。为了充分利用这些大模型的能力&#xff0c;我们需要将其与现有的应用框架进行对接。Sprin…...

完美解决NameError: name ‘file‘ is not defined的正确解决方法,亲测有效!!!

完美解决NameError: name ‘file’ is not defined的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 亲测有效 完美解决NameError: name file is not defined的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01;报错问题解决思路…...

Witness Table 的由来

“Witness Table” 是 Swift 中的一个术语&#xff0c;源于编译原理和类型系统的概念。它被用来表示一种机制&#xff0c;通过这个机制&#xff0c;编译器可以确保某个类型确实实现了它声明遵循的协议中的所有方法和属性。下面是对这个术语的详细解释&#xff1a; 1. 术语来源…...

Python 3 AI 编程助手

Python 3 AI 编程助手 Python 3 是当前最流行的编程语言之一,特别是在人工智能(AI)领域。Python 3 的语法简洁明了,拥有丰富的库和框架,使其成为开发 AI 应用程序的首选语言。本文将介绍 Python 3 在 AI 编程中的关键特性、常用库以及如何使用 Python 3 构建 AI 应用程序…...

【nginx】nginx的配置文件到底是什么结构,到底怎么写?

背景&#xff1a;我window中下载了一个nginx&#xff0c;想要通过nginx来对本地的两个项目做动态代理&#xff0c;但是没想到下载启动都没遇见什么问题&#xff0c;但是在配置nginx.conf配置文件时&#xff0c;遇见了很多问题&#xff0c;查了好久没查到什么特别有用的内容&…...

基于React 实现井字棋

一、简介 这篇文章会基于React 实现井字棋小游戏功能。 二、效果演示 三、技术实现 import {useEffect, useState} from "react";export default (props) > {return <Board/> }const Board () > {let initialState [[, , ], [, , ], [, , ]];const [s…...

文件的换行符,Windows 的 CRLF 和 Linux 的 LF

文件的换行符&#xff0c;Windows 的 CRLF 和 Linux 的 LF&#xff0c;在开发项目时用哪种比较合适&#xff1f; 在开发项目时选择文件的换行符&#xff08;Windows 的 CRLF 或 Linux 的 LF&#xff09;&#xff0c;通常取决于几个因素&#xff0c;包括项目的运行环境、项目的…...

怎样优化 PostgreSQL 中对日期时间范围的模糊查询?

文章目录 一、问题分析&#xff08;一&#xff09;索引未有效利用&#xff08;二&#xff09;日期时间格式不统一&#xff08;三&#xff09;复杂的查询条件 二、优化策略&#xff08;一&#xff09;使用合适的索引&#xff08;二&#xff09;规范日期时间格式&#xff08;三&a…...

B端设计:任何不顾及用户体验的设计,都是在装样子,花架子

B端设计是指面向企业客户的设计&#xff0c;通常涉及产品、服务或系统的界面和功能设计。与C端设计不同&#xff0c;B端设计更注重实用性和专业性&#xff0c;因为它直接影响企业的效率和利益。 在B端设计中&#xff0c;用户体验同样至关重要。不顾及用户体验的设计只是空洞的表…...

React@16.x(51)路由v5.x(16)- 手动实现文件目录参考

作为前面几篇文章的参考&#xff1a; 实现 Router实现 Route实现 Switch实现 withRouter实现 Link 和 NavLink 以上。...

从零开始读RocketMq源码(二)Message的发送详解

目录 前言 准备 消息发送方式 深入源码 消息发送模式 选择发送方式 同步发送消息 校验消息体 获取Topic订阅信息 高级特性-消息重投 选择消息队列-负载均衡 装载消息体发送消息 压缩消息内容 构造发送message的请求的Header 更新broker故障信息 异步发送消息 …...

怎样优化 PostgreSQL 中对布尔类型数据的查询?

文章目录 一、索引的合理使用1. 常规 B-tree 索引2. 部分索引 二、查询编写技巧1. 避免不必要的类型转换2. 逻辑表达式的优化 三、表结构设计1. 避免过度细分的布尔列2. 规范化与反规范化 四、数据分布与分区1. 数据分布的考虑2. 表分区 五、数据库参数调整1. 相关配置参数2. 定…...

mysql在linux系统下重置root密码

mysql在linux系统下重置root密码 登录服务器时候mysql密码忘记了&#xff0c;没办法只能重置&#xff0c;找了一圈&#xff0c;把行之有效的方法介绍在这里。 错误展示&#xff1a; 我还以为yes就可以了呢&#xff0c;这是不行的意思。 关掉mysql服务 sudo systemctl stop …...

设计模式探索:观察者模式

1. 观察者模式 1.1 什么是观察者模式 观察者模式用于建立一种对象与对象之间的依赖关系&#xff0c;当一个对象发生改变时将自动通知其他对象&#xff0c;其他对象会相应地作出反应。 在观察者模式中有如下角色&#xff1a; Subject&#xff08;抽象主题/被观察者&#xf…...

Perl语言入门到高级学习

Perl语言介绍 Perl,全称为Practical Extraction and Report Language,即“实用报表提取语言”,是一种高级、通用、直译式、动态的编程语言。Perl最初由Larry Wall设计,并于1987年12月18日首次发布。经过多年的不断发展和更新,Perl已经成为一种功能丰富且应用广泛的计算机程…...

DOM 基本操作 - 获取元素

theme: smartblue 一、简介 1.1 概念 文档对象模型(Document Object Model),是 W3C 组织推荐的处理可拓展标记语言的标准编程接口。 1.2 DOM 树 二、 获取元素 获取页面中的元素主要可以使用以几种方式&#xff1a; - 根据 ID 获取 - 根据 标签名 获取 - 通过 HTML5 新增的方法…...

Google 搜索引擎:便捷高效、精准查询,带来无与伦比的搜索体验

Google搜索引擎不仅具备检索功能&#xff0c;实则是引领探索万千世界的神秘钥匙。试想&#xff0c;无论何时何地&#xff0c;只需轻触屏幕&#xff0c;所需信息即可唾手可得。便捷与高效&#xff0c;令人叹为观止。其界面设计简约直观&#xff0c;操控体验犹如与未来对话&#…...

tomcat的介绍与优化

tomcat介绍 tomcat和php一样&#xff0c;都是用来处理动态页面的。 tomcat也可以作为web应用服务器&#xff0c;开源的。 php .php tomcat .jsp nginx .html tomcat 是用java代码写的程序&#xff0c;运行的是javaweb应用程序 tomcat的特点和功能&#xff1a; 1.servlet容器…...

Python 插入、替换、提取、或删除Excel中的图片

Excel是主要用于处理表格和数据的工具&#xff0c;我们也能在其中插入、编辑或管理图片&#xff0c;为工作表增添视觉效果&#xff0c;提升报告的吸引力。本文将详细介绍如何使用Python操作Excel中的图片&#xff0c;包含以下4个基础示例&#xff1a; 文章目录 Python 在Excel…...

紧凑型建模的veriloga语句要怎么看?

说点人话&#xff0c;真传一句话&#xff0c;那些一堆公式似是而非的东西&#xff0c;都是半懂不懂的人沽名钓誉用的。 其实建模&#xff0c;归根结底明白几个东西就行了。 1.什么是你的输入和输出信号&#xff1f; 2.你对输入输出信号要建立什么功能关系&#xff1f; 那我们看…...

大语言模型系列-Transformer介绍

大语言模型系列&#xff1a;Transformer介绍 引言 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;Transformer模型已经成为了许多任务的标准方法。自从Vaswani等人在2017年提出Transformer以来&#xff0c;它已经彻底改变了NLP模型的设计。本文将介绍Transforme…...

JavaDS —— 顺序表ArrayList

顺序表 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构&#xff0c;一般情况下采用数组存储。在数组上完成数据的增删查改。在物理和逻辑上都是连续的。 模拟实现 下面是我们要自己模拟实现的方法&#xff1a; 首先我们要创建一个顺序表&#xff0c;顺序表…...

Sphinx 搜索配置

官方文档 http://sphinxsearch.com/docs/sphinx3.html 支持中文&#xff0c;英文&#xff0c;日文&#xff0c;韩文&#xff0c;俄罗斯语搜索 版本是 官网3.6.1版本 文件 sphinx.conf.dist 的windows 配置&#xff0c;官网下载下来后微微配置即可。 # Minimal Sphinx confi…...

如何在不关闭防火墙的情况下,让两台设备ping通

问题现象 如题&#xff0c;做虚拟机实验的时候&#xff0c;有一台linux系统的虚拟机配置的ip地址是192.168.172.181 物理主机的ip地址是192.168.172.1 此时物理主机可以ping通虚拟机 但是虚拟机不能ping通物理主机 此时我们可以想到&#xff0c;有可能是物理主机防火墙的原因。…...

windows USB 设备驱动开发-USB 等时传输

客户端驱动程序可以生成 USB 请求块 (URB) 以在 USB 设备中向/从常时等量端点传输数据。虽然USB设备一向以非等时传输出名&#xff0c;USB提供的是一种串行数据&#xff0c;而非等时&#xff0c;但是USB仍然设计了等时传输的机制&#xff0c;但根据笔者的经验&#xff0c;等时传…...

【文件共享 windows和linux】Windows Server 2016上开启文件夹共享,并在CentOS 7.4上访问和下载文件

要在Windows Server 2016上开启文件夹共享&#xff0c;并在CentOS 7.4上访问和下载文件&#xff0c;请按照以下步骤操作&#xff1a; 在Windows Server 2016上开启文件夹共享&#xff1a; 启用SMB服务&#xff1a; 打开“服务器管理器”。选择“文件和存储服务” > “共享…...

【知网CNKI-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…...

【Python_GUI】tkinter常用组件——文本类组件

文本时窗口中必不可少的一部分&#xff0c;tkinter模块中&#xff0c;有3种常用的文本类组件&#xff0c;通过这3种组件&#xff0c;可以在窗口中显示以及输入单行文本、多行文本、图片等。 Label标签组件 Label组件的基本使用 Label组件是窗口中比较常用的组件&#xff0c;…...