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

这篇具有很好参考价值的文章主要介绍了Android笔记(十八):面向Compose组件结合Retrofit2和Rxjava3实现网络访问。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、Retrofit2

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

二、RxJava3

RxJava3(https://github.com/ReactiveX/RxJava)是响应式编程(Reactive Extensions)的java实现,它基于观察者模式的实现了异步编程接口。RxJava库通过使用可观察的序列来组成异步和基于事件的程序。
compose retrofit,android,笔记,retrofit,RxJava3,Compose

Observable可观察

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

说明
io.reactivex.rxjava3.core.Flowable 0…N流,支持响应式流和背压按照onSubscribe onNext (onError 或onComplete)属性执行,其中onNext可以执行多次,onError和onComplete是互斥的。
io.reactivex.rxjava3.core.Observable 0…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),访问的内容如下所示:
compose retrofit,android,笔记,retrofit,RxJava3,Compose
在下面的例子中,将结合Retrofit2+RxJava3+Compose组件实现对上述资源的访问,并以列表的方式显示。运行结果类似下图:
compose retrofit,android,笔记,retrofit,RxJava3,Compose

1.AndroidManifest.xml配置网络访问

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

<uses-permission android:name="android.permission.INTERNET" />
<application
    android: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 theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    MainScreen()
                 }
            }
        }
    }
}

参考文献

陈轶 第8章 Android网络应用《Android移动应用开发(微课版)》P258-P293 清华大学出版社文章来源地址https://www.toymoban.com/news/detail-785851.html

到了这里,关于Android笔记(十八):面向Compose组件结合Retrofit2和Rxjava3实现网络访问的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android笔记(六):JetPack Compose常见的UI组件

    Text显示的文本来源可以引用res-values-strings.xml中的资源,如第一个显示文本所示。 点击按钮前: 点击按钮后: 点击第一个圆角按钮不放时,显示为按钮:true Button有两方面需要注意: (1) Buttton有一个参数interactionSource,用来监听组件状态的事件源,通过它获取组件的状态来

    2024年02月04日
    浏览(36)
  • Android笔记(七)Android JetPack Compose组件搭建Scaffold脚手架

    在去年2022年曾发布一篇关于脚手架的文章:“Android JetPack Compose组件中Scaffold的应用” 。但是Android的版本从12变更到13及以上版本,导致一些细节的实现存在不同。在本文中,将从头开始介绍整个脚手架的搭建过程。 在Android Studio(版本是Graffie)中新建模块,选择“Empty Activ

    2024年02月04日
    浏览(34)
  • 探索Android Jetpack Compose的Surface组件

    随着声明性 UI 框架 Jetpack Compose 的出现,Android 开发变得更加简洁和直观。在这篇博客中,我们将深入探讨其中的一项基本构建块 —— Surface 组件,了解它如何影响 UI 的显示和设计。 一、Jetpack Compose和Surface组件 二、Surface组件的基本使用 三、影响Surface的属性 一、Jetpack Co

    2024年02月11日
    浏览(39)
  • Android Jetpack组件库(第七部分)---UI工具包 Compose

    Android Jetpack 是 Google 推出的一整套帮助 Android 应用程序开发的库、工具包和架构指南,旨在为 Android 应用程序提供更快,更轻松,更稳定的开发体验。自推出以来已经发展成了一个庞大的技术生态系统,包括了许多使用方便、功能强大的库,以下是其中一些新特性、新组件:

    2024年01月16日
    浏览(38)
  • Android笔记(二十八):在雷电模拟器安卓7.0+上使用Charles抓包详细教程

    由于手头没有合适的真机,所有经常使用雷神模拟器来跑项目,模拟器也需要能够抓包看看接口返回的数据,以便自测调试。本文记录了如何在雷电模拟器安卓7.0+上使用Charles抓包,其他模拟器没试过。 模拟器上浏览器打开百度网页,能抓到百度页面数据 模拟器开启root权限

    2024年02月09日
    浏览(33)
  • Element UI结合vue-cropper打造图片裁剪上传组件,Android开发面试书籍

    left: 0; color: #ccc; font-size: 8px; right: 0; } } } ::v-deep .avatar-uploader .el-upload–text { border: 1px dashed #d9d9d9; border-radius: 6px; margin-right: 20px; cursor: pointer; position: relative; overflow: hidden; } ::v-deep .avatar-uploader .el-upload:hover { border-color: #409eff; } ::v-deep .avatar-uploader-icon { font-size: 22px; color: #ccc; wi

    2024年04月13日
    浏览(36)
  • 安卓学习笔记之五:Android Studio_骰子案例3(Kotlin搭配 Jetpack Compose实现)

    使用 Compose 创建一款交互式  Dice Roller  Android 应用。 完成: 定义可组合函数。 使用组合创建布局。 使用  Button  可组合项创建按钮。 导入  drawable  资源。 使用  Image  可组合项显示图片。 使用可组合项构建交互式界面。 使用  remember  可组合项将组合中的对象存储到内

    2024年02月20日
    浏览(40)
  • [Android Studio]Android 数据存储-文件存储学习笔记-结合保存QQ账户与密码存储到指定文件中的演练

     🟧🟨🟩🟦🟪 Android Debug 🟧🟨🟩🟦🟪 Topic   发布安卓学习过程中遇到问题解决过程,希望我的解决方案可以对小伙伴们有帮助。 🪁文件存储 💾内部存储 📀存储数据到文件 💿从文件中读取数据 💯实战演练--保存QQ账号与密码 📖acticity_main.xml布局文件  📖 FileSave

    2023年04月14日
    浏览(37)
  • 【Android笔记108】Android之翻转视图组件ViewFlipper的使用

    这篇文章,主要介绍Android之翻转视图组件ViewFlipper的使用。 目录 一、翻转视图ViewFlipper 1.1、什么是ViewFlipper 1.2、运行效果 (1)不带动画的效果

    2024年02月08日
    浏览(48)
  • Android笔记(二十一):Room组件实现Android应用的持久化处理

    Room是Android JetPack架构组件之一,是一个持久处理的库。Room提供了在SQLite数据库上提供抽象层,使之实现数据访问。 (1)实体类(Entity):映射并封装了数据库对应的数据表中对应的结构化数据。实体定义了数据库中的数据表。实体类中的数据域与表的列一一对应。 (2)数

    2024年01月20日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包