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

【Android】Serializable和Parcelable序列化对象:传递自定义类数据

在这里插入图片描述

三三要成为安卓糕手

一:Serializable序列化

1:提出问题 && 解决思路

提问:我们现在想传输的数据是一个类怎么办

思路:putExtra方法形参中不能传递自定义类,

①改造我们自己创建的类

②序列化

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2:User类

实现Serializable接口:只用简单实现这个接口就可以了,不用重写什么方法,类在底层被转化成一种字节流的东西,从而达到数据传输的效果

public class User implements Serializable {private String name;//用户名private String age;private int mobile;public User(String name , String age , int mobile){this.name = name;this.age = age;this.mobile = mobile;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public int getMobile() {return mobile;}public void setMobile(int mobile) {this.mobile = mobile;}}

3:数据传输

		else if (id == R.id.btn_second6) {Intent intent = new Intent(this, SerialActivity.class);User user = new User("三三", "18", 123456);intent.putExtra("key_user", user);startActivity(intent);}

4:数据接收

 //接收类数据Intent intent = getIntent();User user = (User) intent.getSerializableExtra("key_user");if (user != null) {String name = user.getName();String age = user.getAge();int mobile = user.getMobile();Log.i(TAG, "onCreate: name = " + name);Log.i(TAG, "onCreate: age = " + age);Log.i(TAG, "onCreate: mobile = " + mobile);} else {Log.e(TAG, "onCreate: user is null");}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(1)getSerializableExtra

双参数的,需要版本在29以上,为了兼顾老版本,优先使用单参数方式

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

getSerializableExtra(String name, Class<T> clazz) :这是 Android API 29 引入的方法,它在获取数据的同时,通过传入目标类型的 Class 对象,直接返回指定类型的数据;比如这段代码

Intent intent = getIntent();MySerializableClass myObj = intent.getSerializableExtra("key", MySerializableClass.class);if (myObj != null) {// 处理 myObj
}

getSerializableExtra(String name) :返回一个 Serializable 类型的对象。获取到数据后,需要强制将其转换为实际需要的类型。

二:Parcelable打包数据

想要让数据传输中性能更好,Android中专门诞生了一个接口Parcelable(包是安卓下的)

顾名思义parcelable 翻译为 “可打包的” (用于跨进程传输)

1:实现Parcelable接口重写方法

public class Student implements Parcelable {private static final String TAG = "Student";private String name;//用户名private String age;//年龄private int mobile;//手机号public Student(String name, String age, int mobile) {this.name = name;this.age = age;this.mobile = mobile;}public Student(Parcel parcel){name = parcel.readString();age = parcel.readString();mobile = parcel.readInt();}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public int getMobile() {return mobile;}public void setMobile(int mobile) {this.mobile = mobile;}@Overridepublic int describeContents() {return 0;}/*** 打包操作*/@Overridepublic void writeToParcel(@NonNull Parcel dest, int flags) {dest.writeString(name);dest.writeString(age);dest.writeInt(mobile);Log.i(TAG, "writeToParcel: ");}/*** 拆包操作*/public static final Creator<Student> CREATOR = new Creator<Student>() {@Overridepublic Student createFromParcel(Parcel source) {Log.i(TAG, "createFromParcel: source" + source);return new Student(source);}@Overridepublic Student[] newArray(int size) {return new Student[0];}};}

2:describeContents

  • 主要用于描述当前对象中包含的特殊对象类型(如文件描述符等)——这里了解即可,用的不多
  • 通常情况下返回 0 即可,只有当对象中包含需要特殊处理的数据时才返回非 0 值

3:writeToParcel-打包

对象序列化的核心方法,将当前对象的所有成员变量写入Parcel 对象中,后续可以通过对应的 CREATORParcel 中恢复对象

(1)@NonNull Parcel dest

参数destdestination 的缩写,意为 “目的地”。传递数据的时候做一个打包的工作

	/*** 打包操作*/@Overridepublic void writeToParcel(@NonNull Parcel dest, int flags) {dest.writeString(name);dest.writeString(age);dest.writeInt(mobile);Log.i(TAG, "writeToParcel: ");}

4:Creator CREATOR-拆包

(1)拆包思路一

返回的是一个Student对象,那就先读取三个变量,在作为构造方法里的参数进行传参,但是不行因为这是静态方法

CREATOR静态内部实现public static final Creator<Student> CREATOR ),方法内部只能访问静态成员变量

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(2)Parcelable 的 “约定玩法”

官方 / 社区习惯上,会给 Parcelable 类专门写一个 protected public 的构造函数,参数是 Parcel,专门用来接收数据,用于反序列化,为对象的成员变量赋值。

public Student(Parcel parcel){name = parcel.readString();age = parcel.readString();mobile = parcel.readInt();}
public static final Creator<Student> CREATOR = new Creator<Student>() {@Overridepublic Student createFromParcel(Parcel source) {Log.i(TAG, "createFromParcel: source" + source);return new Student(source);}@Overridepublic Student[] newArray(int size) {return new Student[0];}};

5:createFromParcel(Parcel source) 方法

作用:从序列化后的 Parcel 对象中读取数据

参数 source:是之前通过 writeToParcel() 写入数据的 Parcel 对象(可以理解为 “数据源”)。

6:newArray(int size) 方法

Student 数组,用于批量反序列化时使用(例如从 Parcel 中读取多个 Student 对象时)。

参数 size:需要创建的数组长度。返回值写成 new Student[size]更合适

三:Parcelable数据传输和接收

1:数据传输

else if (id == R.id.btn_second7) {try {Intent intent = new Intent(this, ParcelActivity.class);Student sansan = new Student("Sansan", "18", 12345);intent.putExtra("key_student", sansan);startActivity(intent);} catch (Exception e) {Log.e(TAG, "跳转ParcelActivity失败: " + e.getMessage(), e);}}

2:数据接收

public class ParcelActivity extends AppCompatActivity {private static final String TAG = "ParcelActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_parcel);Intent intent = getIntent();//注意这段代码,不是new Intent();Student student = intent.getParcelableExtra("key_student");String name = student.getName();String age = student.getAge();int mobile = student.getMobile();Log.i(TAG, "onCreate: name = " + name);Log.i(TAG, "onCreate: age = " + age);Log.i(TAG, "onCreate: mobile" + mobile);}
}

在某个版本之前也是被限定的,用兼容性更好的单个参数即可

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3:结果

通过日志可以看见通过parclable传过来的数据

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

四:插件简化Parcelable开发

Parcelable中很多代码是规范化和统一化的,所以使用一个插件能减少我们的工作量,直接生成模版

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

五:总结

两种传递类数据的方式,前者silizeable简单,后者难但是性能好

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

相关文章:

  • 无人机抗噪模块技术概述!
  • AI + 金融领域 + 落地典型案例
  • AI +金融 = 七大核心维度+ 落地典型困难
  • 基于深度学习CenterPoint的3D目标检测部署实战
  • 《GPT-OSS 模型全解析:OpenAI 回归开源的 Mixture-of-Experts 之路》
  • 使用 FastAPI 的 WebSockets 和 Elasticsearch 来构建实时应用
  • shell脚本——搜索某个目录下带指定前缀的文件
  • 标准解读——71页2025《数字化转型管理 参考架构》【附全文阅读】
  • C++11中的互斥锁,条件变量,生产者-消费者示例
  • Cyberduck (FTP和SFTP工具) v9.2.3.43590
  • SpringBoot3后端项目介绍:mybig-event
  • 华为云之基于鲲鹏弹性云服务器部署openGauss数据库【玩转华为云】
  • 网页作品惊艳亮相!这个浪浪山小妖怪网站太治愈了!
  • AutoGLM2.0背后的云手机和虚拟机分析(非使用案例)
  • 百度地图 添加热区(Hotspot)
  • Ubuntu_22.04安装文档
  • 应用在运行时,向用户索取(相机、存储)等权限,未同步告知权限申请的使用目的,不符合相关法律法规要求--教你如何解决华为市场上架难题
  • 【数据库】Oracle学习笔记整理之六:ORACLE体系结构 - 重做日志文件与归档日志文件(Redo Log Files Archive Logs)
  • Ubuntu 虚拟显示器自动控制服务设置(有无显示器的切换)
  • 机器学习数据预处理总结(复习:Pandas, 学习:preprocessing)
  • iOS 应用迭代与上架节奏管理 从测试包到正式发布的全流程实践
  • 数据预处理:机器学习中的关键步骤
  • 【iOS】NSRunLoop
  • 25_基于深度学习的行人检测识别系统(yolo11、yolov8、yolov5+UI界面+Python项目源码+模型+标注好的数据集)
  • 解决程序无响应自动重启
  • 织梦素材站网站源码 资源付费下载交易平台源码
  • DeepSeek V3.1 完整评测分析:2025年AI编程新标杆
  • 【数据结构】快速排序算法精髓解析
  • 牛津大学xDeepMind 自然语言处理(4)
  • 【Linux仓库】进程等待【进程·捌】