android——rxjava的使用

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、rxjava是什么?
  • 二、使用步骤
    • 1.引入库
    • 2.读入数据
  • 总结


前言

本文介绍项目开发中使用到rxjava的情形,以及详细的代码。


一、rxjava是什么?

RxJava是一个基于事件流实现异步操作的框架,其作用是实现异步操作,类似于Android中的AsyncTask。它是在Java虚拟机(JVM)上使用可观测的序列来构建异步的、基于事件的程序。RxJava结合了观察者模式,迭代器模式和函数式的精华,最早由Netflix公司用于减少REST调用次数,后迁移到Java平台,并得到了广泛的应用。

RxJava的一些主要特点包括支持Java 8 Lambda表达式,支持异步和同步编程,具有单一依赖关系,以及简洁、优雅的代码风格。此外,RxJava还解决了“回调地狱”问题,异步处理不再需要回调一层套一层,而是用链式调用的方式完成不同线程的回调。

对于Android开发者来说,RxJava在开发过程中常与RxAndroid一同使用,RxAndroid是针对RxJava在Android平台上使用的响应式扩展组件。然而,尽管RxJava带来了编程上的便利,但其复杂性也使得一些开发者对其持有保留态度。

二、使用步骤

1.引入库

代码如下(示例):

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

2.rxjava复杂的异步处理

需求:刚进入页面就进行连接(异步返回结果:失败、成功、连接中),点击按钮的时候,有几种状态: 1、连接失败--重新开始连接

        1.1 连接成功 --调阅读的方法

        1.2 连接失败 --UI进行提示失败

2、连接中

         2.1 连接成功 --调阅读的方法

        2.2 连接失败 --UI进行提示失败

3、连接成功 --调阅读的方法
 

实现方式一
class MainActivity : AppCompatActivity() {private val subHandle = SubHandle()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)subHandle.mConsumer = nullsubHandle.connect().subscribe()}fun btRead(view: View) {subHandle.handleStatus {subHandle.read()}}/*** 刚进入页面就进行连接,点击按钮的时候,有几种状态:* 1、连接失败--重新开始连接,*      1.1 连接成功 --调阅读的方法*      1.2 连接失败 --UI进行提示失败* 2、连接中*      2.1 连接成功 --调阅读的方法*      2.2 连接失败 --UI进行提示失败* 3、连接成功 --调阅读的方法*/class SubHandle {var mConsumer: ((Int) -> Unit)? = nullprivate var status = AtomicInteger(-1) // 0连接失败 1正在连接中 2连接成功private var disposable: Disposable? = nullfun connect(): Observable<Int> {status.set(1)Log.e("TAG", "=连接=")return Observable.interval(5, TimeUnit.SECONDS).take(1).map {val random = Random(System.currentTimeMillis())val randomNumber = random.nextInt(3) // 生成一个0到2之间的随机整数Log.e("TAG", "==funA输出$randomNumber")randomNumber}.subscribeOn(Schedulers.io()).doOnNext {if (it == 2) {status.set(2)mConsumer?.invoke(status.get())} else {status.set(0)Log.e("TAG", "连接阅读器失败,给UI提示")}}}fun handleStatus(consumer: (Int) -> Unit) {mConsumer = consumerwhen (status.get()) {0 -> {Log.e("TAG", "连接失败过,正重试连接")disposable?.dispose()disposable = connect().subscribe()}1 -> Log.e("TAG", "正在连接")2 -> mConsumer?.invoke(status.get())}}fun read() {Log.e("TAG", "开始阅读")}}
}
实现方式二
class MainActivity : AppCompatActivity() {private var canRead = falseprivate var connectStatus = 0 //1 代表 SUCC, 2 代表 FAIL, 0 代表 CONNECTINGoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)connect()}private fun connect() {Log.e("TAG", "=连接=")Thread(Runnable {Thread.sleep(5000) // 休眠5秒钟Observable.just(randomStatus()).doOnNext { connectStatus = it }.filter {Log.e("TAG", "it状态" + it)it == 1 && canRead}.subscribeOn(Schedulers.io()).doOnNext { read() }.subscribe()}).start()}fun btRead(view: View) {canRead = trueLog.e("TAG", "点击按钮" + connectStatus)when (connectStatus) {1 -> read() //  1 代表 SUCC2 -> connect() //  2 代表 FAILelse -> {}}}private fun read() {Log.e("TAG", "开始阅读")}private fun randomStatus(): Int {val random = Random(System.currentTimeMillis())return random.nextInt(3)  //生成一个0到2之间的随机整数}
}

3、连续多个弹窗的处理

使用rxjava实现:

class MainActivity : AppCompatActivity() {private val compositeDisposable = CompositeDisposable()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)}@SuppressLint("CheckResult")fun btRead(view: View) {Log.e("TAG", "jjjjjj")showFirstDialog().flatMap { showSecondDialog() }.flatMap { showThirdDialog() }.subscribe({Log.e("TAG", "3个弹窗都选了确定")}, { error ->Log.e("TAG", "点击了取消$error")})}private fun showFirstDialog(): Observable<Unit> {return Observable.create<Unit> { emitter ->val dialog = AlertDialog.Builder(this).setMessage("第一个弹窗").setPositiveButton("确定") { _, _ ->emitter.onNext(Unit) // 发送事件,表示点击了确定按钮}.setNegativeButton("取消") { _, _ ->emitter.onError(Throwable("1取消")) // 发送错误事件,表示点击了取消按钮}.setOnCancelListener {emitter.onError(Throwable("1取消")) // 发送错误事件,表示点击了返回键}.create()dialog.show()emitter.setCancellable { dialog.dismiss() } // 在取消订阅时关闭弹窗}}private fun showSecondDialog(): Observable<Unit> {return Observable.create<Unit> { emitter ->val dialog = AlertDialog.Builder(this).setMessage("第二个弹窗").setPositiveButton("确定") { _, _ ->emitter.onNext(Unit)}.setNegativeButton("取消") { _, _ ->emitter.onError(Throwable("2取消"))}.setOnCancelListener {emitter.onError(Throwable("2取消"))}.create()dialog.show()emitter.setCancellable { dialog.dismiss() }}}private fun showThirdDialog(): Observable<Unit> {return Observable.create<Unit> { emitter ->val dialog = AlertDialog.Builder(this).setMessage("第三个弹窗").setPositiveButton("确定") { _, _ ->emitter.onNext(Unit)}.setNegativeButton("取消") { _, _ ->emitter.onError(Throwable("3取消"))}.setOnCancelListener {emitter.onError(Throwable("3取消"))}.create()dialog.show()emitter.setCancellable { dialog.dismiss() }}}}

协程实现:

fun btRead(view: View) {lifecycleScope.launch {try {showAlertDialog(this@MainActivity, "提示1", "第一个弹窗")showAlertDialog(this@MainActivity, "提示1", "第二个弹窗")showAlertDialog(this@MainActivity, "提示1", "第三个弹窗")} catch (e: Exception) {Log.e("showAlertDialog", "2222111发生异常")}}}private suspend fun showAlertDialog(context: Context, title: String, message: String): Boolean =suspendCancellableCoroutine { ctn ->val activityRef = WeakReference(context as MainActivity)val alertDialog = AlertDialog.Builder(context).setTitle(title).setMessage(message).setPositiveButton("确定") { dialog, _ ->// 点击确定按钮的逻辑处理dialog.dismiss()activityRef.get()?.let {ctn.resume(true) {}}}.setNegativeButton("取消") { dialog, _ ->// 点击取消按钮的逻辑处理dialog.dismiss()activityRef.get()?.let {ctn.resumeWithException(Exception(message + "取消"))}}.setOnCancelListener {activityRef.get()?.let {ctn.resumeWithException(Exception("蒙层取消"))}}.create()alertDialog.show()}

总结

RxJava是一个基于Java语言的Reactive Extensions库,它用于实现异步编程和流式处理,通过将事件和数据流以数据序列的形式进行处理,提高了代码的可读性和可维护性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/615105.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023年终小结

亲爱的小伙伴们&#xff1a; 随着2023年即将结束&#xff0c;我想回顾一下过去一年作为一名程序员的成长和经验&#xff0c;并分享一些我在技术和团队合作方面的收获。 1. 技术成长与学习&#xff1a; 在过去的一年里&#xff0c;我积极追求技术的学习和发展。我深入研究了新…

Canvas 指南与总结

背景 Canvas API 提供了一个通过 JavaScript 和 HTML 的元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。 Canvas API 主要聚焦于 2D 图形。而同样使用元素的 WebGL API 则用于绘制硬件加速的 2D 和 3D 图形。 简单例子 <…

运维管理软件:助力大学校园破浪前行的数字引擎

随着校园信息化的深入推进&#xff0c;智慧校园的建设面临着诸多挑战。庞大的IT环境、复杂的网络架构、多样化的应用需求&#xff0c;都对运维管理提出了更高的要求。同时&#xff0c;数据安全、隐私保护以及高效的资源利用也成为智慧校园运维的核心需求。 在这场数字化时代的浪…

本地静态资源打包出来,本地配置ng访问服务器(uniapp打包成h5后,使用打包资源连接测试环境测试)

1.下载ng https://nginx.org/en/download.html 2.解压下载的压缩包 3.打包h5静态资源 4.将打包出来的资源放入ng -》html文件夹下面 5.进入ng-》conf-》nginx.conf 进行转发配置 6.启动ng服务&#xff0c;点击nginx.exe 7.浏览器直接访问http://localhost:8081/#/&#x…

mysql触发器的简单使用

mysql触发器 触发器是一个特殊的存储过程&#xff0c;在事件delete、insert、update发生时自动执行一条或多条SQL语句&#xff08;执行多条SQL语句需要用begin、end 包裹起来&#xff09; 创建触发器 创建触发器的四大必要条件 唯一的触发器名称触发器关联的表触发器响应的…

Elasticsearch倒排索引详解

倒排索引&#xff1a; 组成 term index(词项索引 &#xff0c;存放前后缀指针) Term Dictionary&#xff08;词项字典&#xff0c;所有词项经过文档与处理后按照字典顺序组成的一个字典&#xff08;相关度&#xff09;&#xff09; Posting List&#xff08;倒排表&#xf…

Web实战丨基于Django与HTML的新闻发布系统

文章目录 写在前面项目简介项目框架实验内容安装依赖库1.创建项目2.系统配置3.配置视图文件4.配置模型文件5.配置管理员文件6.配置模板文件7.创建数据库8.启动项目 运行结果写在后面 写在前面 本期内容&#xff1a;基于Django与HTML的简单新闻发布系统。 项目需求&#xff1a…

快速入门Semantic Kernel:构建您的第一个AI应用

快速入门Semantic Kernel&#xff1a;构建您的第一个AI应用 引言Semantic Kernel基础知识核心功能操作原理 环境准备和安装环境准备安装Semantic Kernel 创建第一个Semantic Kernel项目项目设置示例代码测试和运行 设计有效的Prompt基本原则示例测试和迭代 常见问题和解决方案问…

order by 与 分页 的冲突

order by 与 分页 的冲突 问题背景 Oracle拼接SQL&#xff0c;JAVA使用SQLQueryExecutor执行拼接的SQL&#xff0c;SQL如下&#xff1a; SELECT col_key, col_other_info FROM tb_tableName WHERE col_where_info 一些筛选条件 order by col_updatetime desc 该表中的数…

python股票分析挖掘预测技术指标知识跳空缺口指标详解(5)

本人股市多年的老韭菜&#xff0c;各种股票分析书籍&#xff0c;技术指标书籍阅历无数&#xff0c;萌发想法&#xff0c;何不自己开发个股票预测分析软件&#xff0c;选择python因为够强大&#xff0c;它提供了很多高效便捷的数据分析工具包。 我们已经初步的接触与学习其中数…

cad的模型怎么打散导入3d---模大狮模型网

将CAD中的模型打散并导入3D建模软件&#xff0c;需要以下步骤&#xff1a; 将CAD中的模型进行分组或分层&#xff1a;在CAD中&#xff0c;将模型按照不同的组或层进行分组或分层。这样可以方便地控制每个部分的显示和隐藏&#xff0c;在导入3D建模软件后&#xff0c;也可以更方…

ChatGLM3-6B的本地api调用

ChatGLM3-6B的本地api调用方式 1.运行openai_api_demo路径下的openai_api.py 启动后界面&#xff1a; 注意&#xff1a;本地api调到的前提是——本地部署了ChatGLM3-6B,本地部署的教程可参考&#xff1a; 20分钟部署ChatGLM3-6B 部署了若CUDA可用&#xff0c;默认会以CUDA方…

阿里云OSS上传视频,可分片上传

uniappH5实现 阿里云OSS上传视频 示例图&#xff1a; 上传视频完整示例代码&#xff1a; 使用npm安装SDK开发包&#xff0c;安装命令为 npm install ali-oss --save accessKeyId 和 accessKeySecret 还有 bucket 替换成你的就行。 multipartUpload 的第一个入参是&#x…

[开发语言][c++]:左值、右值、左值引用、右值引用和std::move()

左值、右值、左值引用、右值引用和std::move 1. 什么是左值、右值2. 什么是左值引用、右值引用3. **右值引用和std::move的应用场景**3.1 实现移动语义3.2 **实例&#xff1a;vector::push_back使用std::move提高性能** **4. 完美转发 std::forward**5. Reference 写在前面&…

【分享贴】大话ESD和浪涌

从事电子产品开发的朋友应该都知道&#xff0c;电子产品样机完成之后&#xff0c;会进入产品性能测试阶段&#xff0c;而其中的EMC&#xff08;电磁兼容&#xff09;测试则是至关重要的一项。 EMC&#xff08;电磁兼容&#xff09;又被分为两大类&#xff1a;EMI&#xff08;电…

【React 常用的 TS 类型】持续更新

1&#xff09;定义样式的 TS 类型 【 React.CSSProperties 】 一般定义样式时需要的类型限制&#xff0c;如下&#xff1a; const customStyle: React.CSSProperties {color: blue,fontSize: 16px,margin: 10px,}; 2&#xff09;定义 Input Ref 属性时的 TS 类型限制 【 R…

果然程序员的世界不是 0 就是 1

在一场轰动全球的爱情故事中&#xff0c;OpenAI 的首席执行官、同时也是打破常规的浪漫英雄&#xff0c;奥特曼&#xff0c;与他的基友奥利弗穆尔赫林在夏威夷举行了一场迷人的婚礼。在奥特曼的岛屿别墅附近&#xff0c;这对低调却又令人羡慕的新人&#xff0c;在奥特曼的哥哥杰…

webpack执行流程知识点总结

webpack的运行流程 Webpack 的运行流程是一个串行的过程&#xff0c;从启动到结束会依次执行以下流程&#xff1a; 在以上过程中&#xff0c;Webpack 会在特定的时间点广播出特定的事件&#xff0c;插件在监听到感兴趣的事件后会执行特定的逻辑&#xff0c;并且插件可以调用 We…

Java8新特性-Lambda表达式

java8 新特性 Lambda表达式 Lambda是一个匿名函数, 可以把lambda表达式理解为是一段可以传递的代码,(将代码像数据一样传递) // 比较两个整数的大小------采用匿名内部类的方式Testpublic void test1(){Comparator<Integer> comp new Comparator<Integer>() {Ov…

JAVA毕业设计120—基于Java+Springboot+vue+uniapp的智能小程序商城管理系统(源代码+数据库+15000字论文)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootvueuniapp的智能小程序商城管理系统(源代码数据库15000字论文)120 一、系统介绍 本项目前后端分离&#xff0c;分为用户、商家、管理员三种角色 1、用户&#…