Android笔记(十八):面向Compose组件结合Retrofit2和Rxjava3实现网络访问

一、Retrofit2

Square公司推出的Retrofit2库(https://square.github.io/retrofit/),改变了网络访问的方式。它实现了网络请求的封装。Retrofit库采用回调处理方式,使得通过接口提交请求和相应的参数的配置,就可以获得对应的响应,并可以将响应获得的数据解析成特定的数据格式,例如将JSON数据解析成对象。
Retrofit访问网络资源的流程:
在这里插入图片描述

二、RxJava3

RxJava3(https://github.com/ReactiveX/RxJava)是响应式编程(Reactive Extensions)的java实现,它基于观察者模式的实现了异步编程接口。RxJava库通过使用可观察的序列来组成异步和基于事件的程序。
在这里插入图片描述

Observable可观察

即是一个主题,可以表示任何对象,它可以从数据源中获得数据或者其他的状态值。Observable对象发出数据流。只要有观察者开始接受,Observable就会提供数据,发出数据流。可观察者可以有多个订阅者。
在RxJava3中常见的可观察流如下表所示:

说明
io.reactivex.rxjava3.core.Flowable0…N流,支持响应式流和背压按照onSubscribe onNext (onError 或onComplete)属性执行,其中onNext可以执行多次,onError和onComplete是互斥的。
io.reactivex.rxjava3.core.Observable0…N流,不支持背压按照onSubscribe onNext (onError或onComplete)的顺序执行,onNext可以执行多次,onError与onComplete是互斥的。

Operator操作符

承担了对 Observable 可观察对象发出的事件进行修改和变换。每个Operator操作实际上是一个方法/函数,Observable对象作为输入参数,对于Observable对象发射的每一项数据,它会将在Operator方法/函数中应用这些数据,然后将处理结果以Observable对象形式返回。因此返回的是另外一个Observable对象。这个Observable对象可以继续向后发射或结束。

操作符Operator可以有若干个,形式如下:

dataSource.operator1()
.operator2()
.operator3()

这些操作符之间构成了上下流的关系。

Observer观察者

Observer观察者订阅可观察Observable对象的序列数据,并对可观察对象的每一项做出反应。观察者负责处理事件,它是事件的消费者。每当关联的Observable发出数据时,通知观察者。观察者一个接一个地处理数据。

背压策略

由于可观察者(Observable)和观察者(Observer)是在不同线程中分别实现发送数据和接受数据。由于不同线程中处理的时间伴随着问题的复杂度,会导致二者处理数据的速度出现不同。如果被观察者对象发射的数据的速度远远快于观察者对象处理数据的速度的话,会将数据放入到缓存暂存或者直接放弃这些数据。这两种方法的处理都有不妥之处。因此,需要制定“背压(Back Pressure)”策略,来解决二者在异步场景下,被观察者发射数据和观察者处理数据速度不一致的问题。因此,通常所说的背压是在异步环境下,控制流速的一种策略。常见的背压策略方式如下表所示:

背压策略说明
MISSING表示通过 create 方法创建的 Flowable 没有指定背压策略,不会对通过 OnNext 发射的数据做缓存或丢弃处理,下游必须处理操作符
ERROR发生背压,会发送MissingBackpressureException信号,以免下游不能消费继续。
BUFFER发生背压,会缓存数据,直至下游消化数据完成
DROP发生背压,会如果下游不能继续消费数据,将最近发射的值丢弃

三、网络访问处理实例

假设已经有网络资源 http://127.0.0.1:5000/json/students.json(也可以写成:http://localhost:5000/json/students.json),访问的内容如下所示:
在这里插入图片描述
在下面的例子中,将结合Retrofit2+RxJava3+Compose组件实现对上述资源的访问,并以列表的方式显示。运行结果类似下图:
在这里插入图片描述

1.AndroidManifest.xml配置网络访问

要访问网络需要设置互联网的访问权限,以及在应用中设置明文访问许可:

<uses-permission android:name="android.permission.INTERNET" />
<applicationandroid:usesCleartextTraffic="true" ...>
</application>

2.增加依赖

在项目模块的build.gradle.kt中增加如下依赖:

//retrofit框架
implementation ‘com.squareup.retrofit2:retrofit:2.9.0’
implementation ‘com.squareup.retrofit2:converter-gson:2.9.0’

//增加RxJava库的依赖
implementation “io.reactivex.rxjava3:rxjava:3.1.5”

//增加在Android对RxJava库的支持
implementation ‘io.reactivex.rxjava3:rxandroid:3.0.2’

//增加Retrofit支持RxJava3的CallAdapter
implementation ‘com.squareup.retrofit2:adapter-rxjava3:2.9.0’

implementation “androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1”

也可以根据最新的版本重新调整版本号。

3.定义实体类

data class Student(val id:String,
val name:String,
val gender:String,
val age:Int)

4.定义网络访问

(1)定义网络服务访问接口

interface StudentService{@GET("students.json")fun getStudents(): Flowable<List<Student>>
}

表示访问students.json资源获取一个RxJava3的Flowable可观察者对象。这个可观察者对象封装了包含学生记录的列表。

(2)定义网络服务创建类

object StudentServiceCreator{private val urlStr="http://10.0.2.2:5000/json/"private val retrofit = Retrofit.Builder().baseUrl(urlStr).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJava3CallAdapterFactory.create()).build()fun <T> createService(serviceClass:Class<T>):T = retrofit.create(serviceClass)
}

Web服务器是本地服务器,由于移动模拟器的127.0.0.1已经被占用,因此要在移动端访问本地服务器,可以通过10.0.2.2来访问。
定义Retrofit对象,并在该对象中设置了解析JSON数据的转换对象和并发处理的适配器。

5.定义定义视图模型

定义视图模型,调用的网络访问处理的相关类,获取网络资源。

class StudentViewModel: ViewModel() {private val students:SnapshotStateList<Student> = mutableStateListOf()private val creator  = StudentServiceCreator.createService(StudentService::class.java)fun doNetwork(urlStr:String){creator.getStudents().observeOn(AndroidSchedulers.mainThread()).subscribe{it:List<Student>->if(students.isEmpty()){students.addAll(it)}}}fun getData() = students
}

6.定义界面

(1)定义列表的显示学生记录单项的可组合函数

@Composable
fun StudentItemCard(student: Student){Card(modifier = Modifier.fillMaxWidth().wrapContentHeight().padding(5.dp),elevation = CardDefaults.cardElevation(defaultElevation = 5.dp),colors = CardDefaults.cardColors(containerColor = Color.Blue,contentColor = Color.White)){Column(modifier= Modifier.fillMaxWidth().wrapContentHeight().padding(5.dp)){Text(text = "${student.id}",fontSize = 24.sp)Row(modifier = Modifier.padding(15.dp)){Text(text = "${student.name}",fontSize = 24.sp)Spacer(modifier = Modifier.padding(5.dp))Text(text = "${student.gender}",fontSize = 24.sp)Spacer(modifier = Modifier.padding(5.dp))Text(text = "${student.age}",fontSize = 24.sp)}}}
}

(2)定义学生记录的列表

@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreen(stuVM: StudentViewModel = viewModel()){var students = stuVM.getData()val displayState = remember{ mutableStateOf(false) }Scaffold(floatingActionButton = {FloatingActionButton(onClick = {displayState.value = true//访问网络资源stuVM.doNetwork("http://10.0.2.2:5000/json/students.json")//获取学生记录students = stuVM.getData()}) {Icon(Icons.Filled.Refresh,contentDescription = null)}}){Column(horizontalAlignment = Alignment.CenterHorizontally){Text(modifier = Modifier.fillMaxWidth(),text = "学生记录列表",textAlign = TextAlign.Center,fontSize = 28.sp)if(displayState.value){LazyColumn{items(students){it: Student ->StudentItemCard(student = it)}}}}}
}

7.定义主活动MainActivity

在主活动中调用界面

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {Ch09_DemoTheme {// A surface container using the 'background' color from the themeSurface(modifier = Modifier.fillMaxSize(),color = MaterialTheme.colorScheme.background) {MainScreen()}}}}
}

参考文献

陈轶 第8章 Android网络应用《Android移动应用开发(微课版)》P258-P293 清华大学出版社

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

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

相关文章

辅助电源交流220V转5V200mA输出,不需要变压器

辅助电源交流220V转5V200mA输出&#xff0c;不需要变压器。 在当今智能家居、小家电等电子产品日益普及的时代&#xff0c;对辅助电源的需求也越来越大。一款高效、低成本、小巧封装的辅助电源芯片成为众多产品的迫切需求。今天&#xff0c;我们将为您介绍一款交流220V转5V200m…

Bytebase 2.12.0 - 改进自动补全和布局导航

&#x1f680; 新功能 支持 MySQL 高级自动补全。支持从 UI 上导入分类分级配置。 &#x1f514; 重大变更 作废已有企业版试用证书。之后可以通过提交申请获取新的试用证书。 &#x1f384; 改进 改进整体布局和导航。 支持在 SQL 编辑器里显示以及查询 PostgreSQL 数据…

“机器人V2.0时代已来”-任务规划难题迎刃而解,世界因机器人改变而翻转!

01-VILA背景简介 2022年&#xff0c;Michael Ahn, Anthony Brohan等人提出“Do as i can, not as i say: Grounding language in robotic affordances”算法。本文指出虽然大型语言模型可以编码关于世界的丰富语义知识&#xff0c;而这些知识对旨在对用自然语言表达的高级、时…

MAC配置环境变量

1、配置 JAVA JDK 1.1、查看 JDK 安装目录 &#xff08;1&#xff09;可以在Android Studio中查看&#xff0c;复制该路径 &#xff08;2&#xff09;也可以在官网下载 Java JDK下载地址 mac中的安装地址是"资源库->Java->JavaVirtualMachines"中 1.2、…

SQLMAP的使用(rails 为例)

1.启动一个项目&#xff0c;例如rails学习的项目&#xff0c;修改config/database.yml&#xff0c; 假设来一个接口&#xfeff; class YourModel::YourController < ApplicationController def test_sqlisql "select * from your_table_name where id " par…

scratch认识图形 2023年12月中国电子学会 图形化编程 scratch编程等级考试二级真题和答案解析

目录 scratch认识图形 一、题目要求 1、准备工作 2、功能实现 二、案例分析

编程性能调优方案

微信公众号转载&#xff0c;关注微信公众号掌握更多技术动态 --------------------------------------------------------------- 一、字符串与集合性能优化 1.String 对象的实现 在 Java 语言中&#xff0c;Sun 公司的工程师们对 String 对象做了大量的优化&#xff0c;来节…

【机器学习】利用线性回归预测披萨价格

目录 前言 一、绘制散点图 二、数据准备 三、一元线性回归模型训练 四、一元线性回归模型评估 总结 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很高兴与大家相识&#xff0c;希望我的博客能对你有所帮助。 &#x1f4a1;本文由Filotimo__✍️原创&#xff0c;首…

vue运行项目时network:unavailble的解决方法

先看问题&#xff1a; 解决方法&#xff1a; 1、找到环境变量 2、找到系统变量中的变量Path&#xff1a;点击编辑 3、打开后新建文本 C:\windows\System32\Wbem 复制粘贴即可 3、最后重启vscode运行即可&#xff1a; 错误原因&#xff1a; 因为WBEM是管理协议和网络标准技术…

‘BLEUUID‘ does not name a type错误怎么解决?

摘要&#xff1a;arduino环境下对esp32蓝牙编程时会遇到BLEUUID does not name a type错误&#xff0c;本文介绍解决方法。 硬件设备是安信可ESP32-S模组。 错误发生在代码最开始的地方&#xff0c;include了一个蓝牙设备头文件&#xff0c;然后定义了UUID&#xff0c;注意看&a…

HTTP 302错误:临时重定向

在Web开发中&#xff0c;HTTP状态码是用于表示Web服务器响应的各种状态。其中&#xff0c;HTTP 302错误表示临时重定向&#xff0c;这意味着请求的资源已被临时移动到其他位置&#xff0c;并且服务器已经提供了新的URL&#xff0c;以便客户端可以重新发送请求。 了解HTTP 302错…

言简意赅的 el-table 跨页多选

步骤一 在<el-table>中:row-key"getRowKeys"和selection-change"handleSelectionChange" 在<el-table-column>中type"selection"那列&#xff0c;添加:reserve-selection"true" <el-table:data"tableData"r…

联邦蒸馏中的分布式知识一致性 | TIST 2024

联邦蒸馏中的分布式知识一致性 | TIST 2024 联邦学习是一种隐私保护的分布式机器学习范式&#xff0c;服务器可以在不汇集客户端私有数据的前提下联合训练机器学习模型。通信约束和系统异构是联邦学习面临的两大严峻挑战。为同时解决上述两个问题&#xff0c;联邦蒸馏技术被提…

前端非常好用的免费网页工具推荐(值得收藏)

1、iloveimg 可在线进行图片编辑、压缩、转换等功能&#xff0c;操作方便&#xff0c;完全免费 2、草料二维码 可在线进行文本、网站、文件、图片、微信等二维码生成 3、比特虫 在线制作网站 ico 图标 4、facicongrabber 免费网页 favicon 提取 5、bazhan.wang 在线扒站工…

Docker知识点整理

Docker和虚拟机技术的区别&#xff1a; 传统的虚拟机&#xff0c;可以虚拟出一条硬件&#xff0c;运行一个完整的操作系统&#xff0c;在这个操作系统上安装和运行所需的软件 容器内的应用可以直接运行在宿主 主机的内核中&#xff0c;容器没有自己的内核&#xff0c;也不用虚…

java导出excel通用工具(POI,类注解形式)

通过给类定义注解(设置名称&#xff0c;设置kv转换值)&#xff0c;然后利用设置的名称和传入的数据进行导出。 只需要在项目添加两个工具类就可以实现excel导出功能。 1、单sheet 步骤&#xff1a;1、根据业务需求定义导出的类&#xff0c;并设置表头名称。 …

【媒体开发】利用FFMPEG进行推拉流

目录 1. 下载并启动媒体服务 2. 使用 FFMPEG 拉流并推送到指定服务地址 3. 客户端拉流 1. 下载并启动媒体服务 MediaMTX&#xff0c;也即之前的rtsp-simple-server&#xff0c;是一个即用型、零依赖的实时媒体服务器和媒体代理&#xff0c;允许发布、读取、代理和记录视频和…

Web安全-SQL注入常用函数(二)

★★实战前置声明★★ 文章中涉及的程序(方法)可能带有攻击性&#xff0c;仅供安全研究与学习之用&#xff0c;读者将其信息做其他用途&#xff0c;由用户承担全部法律及连带责任&#xff0c;文章作者不承担任何法律及连带责任。 1、MySQL数据库构成 初始化安装MySQL数据库后(…

智能优化算法应用:基于模拟退火算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于模拟退火算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于模拟退火算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.模拟退火算法4.实验参数设定5.算法结果6.…

Android---Kotlin 学习007

集合可以方便你处理一组数据&#xff0c;也可以作为值参传给函数&#xff0c;和我们学过的其它变量类型一样&#xff0c;List、Set 和 Map 类型的变量也分为两类&#xff0c;只读和可变。 List创建与元素获取 通过 listOf() 函数创建一个 List 集合。 val listString : List&…