当前位置: 首页 > 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.xdnf.cn/news/1125703.html

相关文章:

  • python原生处理properties文件
  • 第十四章 Stream API
  • 【第二章自定义功能菜单_MenuItemAttribute_顶部菜单栏(本章进度1/7)】
  • 零售企业用户行为数据画像的授权边界界定:合规与风险防范
  • 16、鸿蒙Harmony Next开发:组件扩展
  • RAG实战指南 Day 16:向量数据库类型与选择指南
  • Django+Celery 进阶:动态定时任务的添加、修改与智能调度实战
  • 第三章 OB SQL 引擎高级技术
  • PostgreSQL 数据库中 ETL 操作的实战技巧
  • 深入探讨Hadoop YARN Federation:架构设计与实践应用
  • docker搭建freeswitch实现点对点视频,多人视频
  • 综合网络组网实验(机器人实验)
  • Java 避免空指针的方法及Optional最佳实践
  • 【Linux系统】命令行参数和环境变量
  • 【Java篇】IntelliJ IDEA 安装与基础配置指南
  • 网络安全职业指南:探索网络安全领域的各种角色
  • 蛋白质组学技术揭示超急性HIV-1感染的宿主反应机制
  • HR数字化转型:3大痛点解决方案与效率突破指南
  • 渭河SQL题库-- 来自渭河数据分析
  • 在 SymPy 中精确提取三角函数系数的深度分析
  • Spring Boot - Spring Boot 集成 MyBatis 分页实现 RowBounds
  • MySQL高级篇(二):深入理解数据库事务与MySQL锁机制
  • AutoGPT vs BabyAGI:自主任务执行框架对比与选型深度分析
  • 【PTA数据结构 | C语言版】二叉树层序序列化
  • TiD2025 | openKylin基础设施平台创新实践分享,构筑开源质量根基
  • ZYNQ千兆光通信实战:Tri Mode Ethernet MAC深度解析
  • 全面安装指南:在Linux、Windows和macOS上部署Apache Cassandra
  • 基于多智能体强化学习的医疗检索增强生成系统研究—MMOA-RAG架构设计与实现
  • wpf Canvas 动态增加右键菜单
  • Kafka与Flink打造流式数据采集方案:以二手房信息为例