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

Android笔记(四)Activity之间传递可序列化的数据的优化处理

Activity之间传递可序列化的数据

Android应用开发会常常处理数据的序列化和传递。在Android中往往采用两种方式实现数据的可序列化:(1)实现java.io.Serializable接口(2)实现android.os.Parcelable接口。
将类定义为android.os.Parcelable接口的方式,实际上是利用Parcel提供了一套机制,将一个完整的对象进行分解,而分解后的每一部分的数据都属于Intent支持的数据类型。可以将分解后的可序列化的数据写入到一个共享内存中,其他进程通过Parcel可以从这块共享内存中读出字节流,并反序列化成对象通过这种方式来实现传递对象的功能。因为这种数据传递方式效率更高,成为Android进行可序列化传递数据的主要方式。
在这里插入图片描述
现在有一个简单实例,就是从主活动MainActivity发送分别发送不同类型数据对象给两个不同的活动,例如将Student类型的数据对象发送给FirstActivity和将Teacher类型的数据对象发送给SecondActivity. 运行效果如下图所示:
在这里插入图片描述

一、定义实现Parcelable数据类

1.Student类

data class Student(val id:String,val name:String,val gender:String,val className:String):Parcelable{constructor(parcel: Parcel) : this(parcel.readString()!!,parcel.readString()!!,parcel.readString()!!,parcel.readString()!!)override fun describeContents(): Int=0override fun writeToParcel(dest: Parcel, flags: Int) {dest.writeString(id)dest.writeString(name)dest.writeString(gender)dest.writeString(className)}companion object CREATOR : Parcelable.Creator<Student> {override fun createFromParcel(parcel: Parcel): Student {return Student(parcel)}override fun newArray(size: Int): Array<Student?> {return arrayOfNulls(size)}}
}

2.结合kotlin-parcelize插件简化数据类的定义

上述可序列化的数据类的定义形式非常复杂,可以结合kotlin-parcelize插件简化数据类的定义。要使用kotlin-parcelize插件,需要在模块对应的build.gradle.kts中增加kotlin-parcelize插件的处理:

plugins {

id (“kotlin-parcelize”)
}

同步配置后,修改上述的Student类和Teacher类为如下形式:
Student类修改为:

@Parcelize
data class Student(val id:String,val name:String,val gender:String,val className:String):Parcelable

定义的Teacher类形式如下:

@Parcelize
data class Teacher(val id:String,val name:String,val gender:String):Parcelable

二、结合JetPack Compose组件定义界面

1.定义MainActivity及其对应的界面

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {MainScreen()}}
}@Composable
fun MainScreen(modifier: Modifier = Modifier) {val context = LocalContext.currentBox(contentAlignment= Alignment.Center){Column(horizontalAlignment = Alignment.CenterHorizontally){Button(modifier = Modifier.width(200.dp),onClick={val intent = Intent(context,FirstActivity::class.java)intent.putExtra("data",Student("20234454","张三","男","计算机2231班"))context.startActivity(intent)}){Text(text = "FirstActivity",fontSize = 18.sp)Icon(imageVector=Icons.Filled.ArrowForward,contentDescription = "第一个活动")}Button(modifier = Modifier.width(200.dp),onClick={val intent = Intent(context,SecondActivity::class.java)intent.putExtra("data",Teacher("20234458","李四","男"))context.startActivity(intent)}){Text(text = "SecondActivity",fontSize = 18.sp)Icon(imageVector=Icons.Filled.ArrowForward,contentDescription = "第二个活动")}}}
}

在MainActivity中通过两个按钮发送数据给不同的活动,发送的数据对象所属的类各不相同。

2.以传统的方式接受传递的数据

传统的方式,就是通过具体指定类型来接受指定类型的数据。
以FirstActivity接受数据为例:

class FirstActivity : ComponentActivity()  {@RequiresApi(Build.VERSION_CODES.TIRAMISU)override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent{FirstScreen()}}
}@RequiresApi(Build.VERSION_CODES.TIRAMISU)
@Composable
fun FirstScreen(){val context = LocalContext.current as Activityval receivedData = context.intent.getParcelableExtra("data",Student::class.java)Box(modifier= Modifier.fillMaxSize().background(Color.Green),contentAlignment = Alignment.Center){Text( text ="第一个界面,接受数据是${receivedData}",fontSize=30.sp,color = Color.Yellow)}
}

以SecondActivity为例:

class SecondActivity : ComponentActivity()  {@RequiresApi(Build.VERSION_CODES.TIRAMISU)override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent{SecondScreen()}}
}@RequiresApi(Build.VERSION_CODES.TIRAMISU)
@Composable
fun SecondScreen(){val context = LocalContext.current as Activityval receivedData = context.intent.getParcelableExtra("data",Teacher::class.java)Box(modifier= Modifier.fillMaxSize().background(Color.Green),contentAlignment = Alignment.Center){Text( text ="第二个界面,接受数据是${receivedData}",fontSize=30.sp,color = Color.Yellow)}
}

观察上述两个活动对应的界面,可以发现,它们主要是处理(1)前后景颜色不同;(2)接受传递的数据类型不同;(3)显示文本的内容不同。其他的具体操作非常类似。因此考虑简化代码,定义一个通用的界面函数。

3.定义通用界面简化处理

定义通用的界面组合函数SubScreen如下:

@RequiresApi(Build.VERSION_CODES.TIRAMISU)
@Composable
fun <T:Parcelable> SubScreen(title:String,preColor:Color,backgroundColor:Color,receivedDataType:Class<T>){val context = LocalContext.current as Activityval data = context.intent.getParcelableExtra("data",receivedDataType)Box(modifier= Modifier.fillMaxSize().background(backgroundColor),contentAlignment = Alignment.Center){Text( text ="$title,接受数据是${data}",fontSize=30.sp,color = preColor)}
}

将两个界面不同的内容:(1)前后景颜色不同;(2)接受传递的数据类型不同;以参数的方式进行传递。
在上述代码中T表示实现接口Parcelable的类型参数,然后指定接受数据的类型参数receivedDataType设置为通用的表示:Class。经过这样的处理,在接受数据时,就达到了不管发送方发送的数据对象所属类型到底是什么类型,只要它实现了android.os.Parcelable接口,就可以直接接受这样类型的对象实例。

val context = LocalContext.current as Activity
val data = context.intent.getParcelableExtra(“data”,receivedDataType)

通过这样的处理,代码会更简单。

4.不同活动调用通用界面

重新修改FirstActivity,调用SubScreen函数定义界面,代码如下:

class FirstActivity : ComponentActivity()  {@RequiresApi(Build.VERSION_CODES.TIRAMISU)override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent{SubScreen(title = "第一个界面", backgroundColor=Color.Green,preColor = Color.Yellow, receivedDataType = Student::class.java)}}
}

重新修改SecondActivity,调用SubScreen函数定义界面,代码如下:

class SecondActivity : ComponentActivity()  {@RequiresApi(Build.VERSION_CODES.TIRAMISU)override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent{SubScreen(title = "第二个界面", backgroundColor = Color.Blue,preColor = Color.Yellow, receivedDataType = Teacher::class.java)}}
}

参考文献

**陈轶《Android移动应用开发(微课版)》[M] 北京:清华大学出版社 2022

相关文章:

Android笔记(四)Activity之间传递可序列化的数据的优化处理

Activity之间传递可序列化的数据 Android应用开发会常常处理数据的序列化和传递。在Android中往往采用两种方式实现数据的可序列化&#xff1a;&#xff08;1&#xff09;实现java.io.Serializable接口&#xff08;2&#xff09;实现android.os.Parcelable接口。 将类定义为an…...

MySQL MVCC详细介绍

MVCC概念 MVCC(Multi-Version Concurrency Control) 多版本并发控制&#xff0c;是一种并发控制机制,用于处理数据库中的并发读写操作&#xff0c;它通过在每个事务中创建数据的快照&#xff0c;实现了读写操作的隔离性&#xff0c;从而避免了读写冲突和数据不一致的问题。 M…...

Element Plus阻止 el-dropdown、el-switch等冒泡事件

最近做vue3项目&#xff0c;使用Element Plus,又遇到坑了&#xff01; 问题点&#xff1a;组件中遇到事件冒泡问题了&#xff0c;el-checkbox 中 change事件要求阻止冒泡&#xff0c;如下代码中要求点击checkbox时不调用li标签的show方法 <li click"show()">…...

Spring framework Day13:注解结合Java配置类

前言 前面我们管理 bean 都是在 xml 文件中去管理&#xff0c;本次我们将介绍如何在 Java 配置类中去管理 bean。 注解结合 Java 配置类是一种常见的 Spring 注入 Bean 的方式。通常情况下&#xff0c;开发人员会使用 Java Config 来定义应用程序的配置信息&#xff0c;而在 …...

彻底卸载自己安装的python

一.彻底卸载自己安装的python Python3 安装完后&#xff0c;在系统中不同目录下存在各种依赖关系&#xff0c;若需卸载&#xff0c;需要一步步无残留完全卸载干净。 删除Python 3.7 框架&#xff0c;打开终端&#xff0c;输入 sudo rm -rf /Library/Frameworks/Python.frame…...

ES相关面试问题整理

索引模板了解么 索引模板&#xff0c;一种复用机制&#xff0c;就像一些项目的开发框架如 Laravel 一样&#xff0c;省去了大量的重复&#xff0c;体力劳动。当新建一个 Elasticsearch 索引时&#xff0c;自动匹配模板&#xff0c;完成索引的基础部分搭建。 模板定义&#xf…...

MytatisP详解

MP详解 一、基础使用1.引入2.Entry中的常用注解3.BaseMapper 、IService、ServiceImpl3.1BaseMapper 3.2IService、ServiceImpl 4.常用配置4.1 application.yml配置4.2 configuration 配置 5.Wrapper6.分页6.1使用分页方式一 7.自定义分页&#xff1a;查询指定列7.1 先用MP的分…...

设计符合REST原则的API可以遵循以下步骤

设计符合REST原则的API可以遵循以下步骤&#xff1a; 定义资源&#xff1a;首先需要将需要交换的数据抽象成资源&#xff0c;即可以将数据看作是一种资源&#xff0c;并且为每种资源定义一个唯一的标识符。 设计URL&#xff1a;使用短的、有意义的方式来表示资源的状态。例如&…...

编程助手成为编程高手,帮您正则调试

官方下载地址&#xff1a;安果移动 视频演示地址&#xff1a;编程助手-正则调试与面试题&#xff0c;升职加薪不是梦_哔哩哔哩_bilibili 编程助手成为编程高手&#xff0c;帮您正则调试 软件介绍版本号 1.0.2更新日期 2023-10-11 找工作不敢谈薪资&#xff1f;总觉得公司欠我…...

opencv 双目立体视觉

单目标定 1.先单目标定每个相机,获得单个相机内参,外参,畸变参数。 双目标定 2.然后双面标定 2.1 stereoCalibrate (标定函数): double stereoCalibrate(InputArrayOfArrays objectPoints, //世界坐标系 InputArrayOfArrays imagePoints1, //左图像点 InputArrayOfA…...

如何将jpg转化为png?

如何将jpg转化为png&#xff1f;可能有的小伙伴就会疑惑了&#xff0c;jpg和png都是图片常用的一种格式&#xff0c;为什么要进行格式的更改呢&#xff1f;那是因为PNG格式具有更好的图片质量和更少的失真。JPG&#xff08;或JPEG&#xff09;格式的图片通常是压缩过的&#xf…...

查看 SSH 登录失败日志

查看日志文件 cat /var/log/auth.log查看 SSH 登录失败的记录 grep "Failed password\|authentication failure" /var/log/auth.log...

竞赛选题 深度学习+opencv+python实现车道线检测 - 自动驾驶

文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络3.1卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV56 数据集处理7 模型训练8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &am…...

MR混合现实模拟消防安全演练场景实训

混合现实&#xff08;MR&#xff09;是一种将虚拟世界与真实世界相结合的技术。它允许教师将数字元素融入实际场景&#xff0c;使学生在亲身体验中学习消防安全知识。这种方式不仅可以激发学生的学习兴趣&#xff0c;还能增强学生的记忆效果。 在MR的助力下&#xff0c;消防安全…...

geecg-uniapp 同源策略 数据请求 获取后台数据 进行页面渲染 ui库安装 冲突解决(3)

一&#xff0c;同源策略 &#xff08;1&#xff09;首先找到env 要是没有env 需要创建一个替换成后端接口 &#xff08;2&#xff09;因为他封装了 先找到 http 请求位置一级一级找 然后进行接口修改 &#xff08;3&#xff09;appUpdata 修改接口 运行即可 &#x…...

Krypton控件组使用之KryptonRibbon

1.去掉File按钮 2.去掉 Cutomize 菜单...

低压配电系统中浪涌保护器的作用,安装位置和接线方法

低压配电系统是指在变压器低压侧或用户侧的电气装置&#xff0c;主要用于向用户提供安全、可靠和经济的电能。低压配电系统中常见的电气设备有低压配电柜、分支箱、开关箱、插座、照明等。这些设备都需要防止因外部或内部原因产生的过电压对其造成损坏或影响其正常工作。过电压…...

OpenCV实现答题卡自动打分!

目录 1&#xff0c;主要原理以及函数介绍 全部代码&#xff0c;以 2 &#xff0c; 实现过程 3&#xff0c;结果展示 1&#xff0c;主要原理以及函数介绍 ap argparse.ArgumentParser() 创建一个ArgumentParser对象&#xff0c;并将其赋值给变量ap。这个对象可以接受我们的脚…...

Python编程必备:掌握列表遍历的6种神级技巧!

更多资料获取 &#x1f4da; 个人网站&#xff1a;涛哥聊Python 遍历列表是Python中最常见的任务之一&#xff0c;因为列表是一种非常常用的数据结构&#xff0c;它用于存储一组项目。 在编程中&#xff0c;经常需要对这些项目进行操作&#xff0c;例如查找特定元素&#xff…...

nodejs+vue校园失物招领平台

失物人可以在该平台中发布自己的拾物信息&#xff0c;本毕业设计题目将设计与实现一个基于校园的非商业行为的网上校园失物招领平台。并给出自己附加的各项条件&#xff0c; 失物招领管理系统主要分为两个部分&#xff0c;涉及前台和后台&#xff0c;然后由失主通过校园失物招…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...