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

【安卓笔记】RxJava之flatMap的使用

0. 环境:

电脑:Windows10

Android Studio: 2024.3.2

编程语言: Java

Gradle version:8.11.1

Compile Sdk Version:35

Java 版本:Java11

1. 写该篇文章的由来

上篇文章中,最后的例子:

// 缩进过多的示范// clicks 传入view, 也就是button这个view。此处是使用viewBinding框架
// Button btn = findViewById(R.id.button); 此处传入btn也是一样的
RxView.clicks(binding.buttonRequest).throttleFirst(2000, TimeUnit.MILLISECONDS) //防抖动,2秒内只响应第1次.subscribe(new Consumer<Unit>() {//此处的Unit可以不用接收@Overridepublic void accept(Unit unit) throws Throwable {// 网络请求,获取项目http。与getProjectHttp() 函数一样netApi.getProject().compose(rxud()).subscribe(new Consumer<ProjectBean>() {@Overridepublic void accept(ProjectBean projectBean) throws Throwable {Log.i(TAG, "accept: " + projectBean);// 此处可以通过获得的projectBean,继续请求Itemfor (ProjectBean.DataDTO data : projectBean.getData()) {netApi.getProjectItem(1,data.getId()).compose(rxud()).subscribe(new Consumer<ItemBean>() {@Overridepublic void accept(ItemBean itemBean) throws Throwable {Log.i(TAG, "accept: " + itemBean);}});}}});}});

如果最后for循环中,替换成调用netApi,则会造成缩进的代码太多阅读困难的问题。

实际上,现在只有两个网络请求。当数量继续增加时,缩进的代码会更多。非常不优雅 

2. 优化1.中的代码

先贴上最终代码:

// clicks 传入view, 也就是button这个view。此处是使用viewBinding框架
// Button btn = findViewById(R.id.button); 此处传入btn也是一样的
RxView.clicks(binding.buttonRequest).throttleFirst(2000, TimeUnit.MICROSECONDS) //防抖动,2秒内只响应第1次.observeOn(Schedulers.io()) // 切换成子线程.flatMap(new Function<Unit, ObservableSource<ProjectBean>>() {@Overridepublic ObservableSource<ProjectBean> apply(Unit unit) throws Throwable {// 获取项目数据return netApi.getProject();}}).flatMap(new Function<ProjectBean, ObservableSource<ProjectBean.DataDTO>>() {@Overridepublic ObservableSource<ProjectBean.DataDTO> apply(ProjectBean projectBean) throws Throwable {// 迭代器,遍历projectBean中 List<Data> 的数据return Observable.fromIterable(projectBean.getData());}}).flatMap(new Function<ProjectBean.DataDTO, ObservableSource<ItemBean>>() {@Overridepublic ObservableSource<ItemBean> apply(ProjectBean.DataDTO dataDTO) throws Throwable {// 获取项目item的数据return netApi.getProjectItem(1, dataDTO.getId());}}).observeOn(AndroidSchedulers.mainThread()) // 切换到主线程,方便操作UI.subscribe(new Consumer<ItemBean>() {@Overridepublic void accept(ItemBean itemBean) throws Throwable {// 最后得到 item,操作UILog.i(TAG, "accept: " + itemBean.toString());}})
;

其中代码对比:

第一个,获取项目信息的http的部分:

// 旧代码
.subscribe(new Consumer<Unit>() {//此处的Unit可以不用接收@Overridepublic void accept(Unit unit) throws Throwable {// 网络请求,获取项目http。与getProjectHttp() 函数一样netApi.getProject()·····}
});// 等价于// 优化后的代码
.flatMap(new Function<Unit, ObservableSource<ProjectBean>>() {@Overridepublic ObservableSource<ProjectBean> apply(Unit unit) throws Throwable {// 获取项目数据return netApi.getProject();}
})

 第二个,for循环部分

// 旧代码
for (ProjectBean.DataDTO data : projectBean.getData()) {····
}// 等价于// 优化后的代码
.flatMap(new Function<ProjectBean, ObservableSource<ProjectBean.DataDTO>>() {@Overridepublic ObservableSource<ProjectBean.DataDTO> apply(ProjectBean projectBean) throws Throwable {// 迭代器,遍历projectBean中 List<Data> 的数据return Observable.fromIterable(projectBean.getData());}
})

第三个,获取item信息的http的部分:

// 旧代码
netApi.getProjectItem(1,data.getId()).compose(rxud())···// 等价于//优化后的代码
.flatMap(new Function<ProjectBean.DataDTO, ObservableSource<ItemBean>>() {@Overridepublic ObservableSource<ItemBean> apply(ProjectBean.DataDTO dataDTO) throws Throwable {// 获取项目item的数据return netApi.getProjectItem(1, dataDTO.getId());}
})

最后的.subscribe是一样的。

比较难理解的部分,在于for循环等价于迭代器,也就是第二步。

稍微解释一下,ObservableSource对象可以往下一张卡片发多次对象。

通过Observable.fromIterable(projectBean.getData()); 就可以遍历projectBean.getData()(即List<Data>)数组中的所有数据。

下一张卡片,会一条一条收到数据,并且一条一条按业务逻辑处理。

这样就可以提高代码可阅读性,解决缩进过多的问题

3. 写在最后

.flatMap 稍微难理解,但是也稍微高级。

请多查阅资料,务必弄懂该函数。

你与其他程序员的差距,就在此刻体现。

请加油学习。

关于RxJava,可以查看我其他文章:

【安卓笔记】RxJava的使用+修改功能+搭配retrofit+RxView防快速点击:https://blog.csdn.net/liosen/article/details/149340103

【安卓笔记】RxJava之flatMap的使用:https://blog.csdn.net/liosen/article/details/149343166

【安卓笔记】RxJava的onNextDo的使用:https://blog.csdn.net/liosen/article/details/149343321

http://www.lryc.cn/news/589109.html

相关文章:

  • PyTorch笔记6----------神经网络案例
  • 【人工智能99问】神经网络的工作原理是什么?(4/99)
  • Android中Launcher简介
  • MySQL索引与事务详解:用大白话讲透核心概念
  • compose、 pipe 组合函数实现
  • 从底层技术到产业落地:优秘企业智脑的 AI 革命路径解析
  • Basilisk库教程(二)
  • QT——QList的详细讲解
  • SpringBoot3.0 +GraalVM17 + Docker
  • AI大模型训练相关函数知识补充
  • MongoDB基础增删改查命令
  • vscode配置运行完整C代码项目
  • B/S 架构通信原理详解
  • 高标准农田气象站的功能
  • 亚矩阵云手机:破解 Yandex 广告平台多账号风控难题的利器
  • 云服务器如何管理数据库(MySQL/MongoDB)?
  • 《大数据技术原理与应用》实验报告四 MapReduce初级编程实践
  • Keepalived双机热备概述
  • 死锁问题以及读写锁和自旋锁介绍【Linux操作系统】
  • Sersync和Rsync部署
  • 免杀学习篇(1)—— 工具使用
  • Dify的默认端口怎么修改
  • 算法学习day16----Python数据结构--模拟队列
  • Nuxt3宝塔PM2管理器部署
  • linux系统------LVS+KeepAlived+Nginx高可用方案
  • LVS(Linux Virtual Server)详细笔记(理论篇)
  • 李宏毅《生成式人工智能导论》 | 第9讲 AI Agent
  • Jfinal+SQLite java工具类复制mysql表数据到 *.sqlite
  • 设计模式笔记_结构型_适配器模式
  • Redis 中的持久化机制:RDB 与 AOF