首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【Android】Serializable和Parcelable序列化对象:传递自定义类数据

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

作者头像
三三是该溜子
发布2025-08-21 08:39:49
发布2025-08-21 08:39:49
3110
举报
文章被收录于专栏:该溜子的专栏该溜子的专栏

三三要成为安卓糕手

一:Serializable序列化

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

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

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

①改造我们自己创建的类

②序列化

2:User类

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

代码语言:javascript
复制
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:数据传输

代码语言:javascript
复制
		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:数据接收

代码语言:javascript
复制
 //接收类数据
        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 对象,直接返回指定类型的数据;比如这段代码

代码语言:javascript
复制
Intent intent = getIntent();
	MySerializableClass myObj = intent.getSerializableExtra("key", MySerializableClass.class);
	if (myObj != null) {
    // 处理 myObj
}

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

二:Parcelable打包数据

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

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

1:实现Parcelable接口重写方法

代码语言:javascript
复制
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;
    }


    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * 打包操作
     */
    @Override
    public 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>() {
        @Override
        public Student createFromParcel(Parcel source) {
            Log.i(TAG, "createFromParcel: source" + source);
            return new Student(source);
        }

        @Override
        public Student[] newArray(int size) {
            return new Student[0];
        }
    };


}

2:describeContents

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

3:writeToParcel-打包

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

(1)@NonNull Parcel dest

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

代码语言:javascript
复制
	/**
     * 打包操作
     */
    @Override
    public 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,专门用来接收数据,用于反序列化,为对象的成员变量赋值。

代码语言:javascript
复制
public Student(Parcel parcel){
        name = parcel.readString();
        age = parcel.readString();
        mobile = parcel.readInt();

    }
代码语言:javascript
复制
public static final Creator<Student> CREATOR = new Creator<Student>() {
        @Override
        public Student createFromParcel(Parcel source) {
            Log.i(TAG, "createFromParcel: source" + source);
            return new Student(source);
        }

        @Override
        public 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:数据传输

代码语言:javascript
复制
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:数据接收

代码语言:javascript
复制
public class ParcelActivity extends AppCompatActivity {
    private static final String TAG = "ParcelActivity";

    @Override
    protected 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简单,后者难但是性能好

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-08-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一:Serializable序列化
    • 1:提出问题 && 解决思路
    • 2:User类
    • 3:数据传输
    • 4:数据接收
      • (1)getSerializableExtra
  • 二:Parcelable打包数据
    • 1:实现Parcelable接口重写方法
    • 2:describeContents
    • 3:writeToParcel-打包
      • (1)@NonNull Parcel dest
    • 4:Creator CREATOR-拆包
      • (1)拆包思路一
      • (2)Parcelable 的 “约定玩法”
    • 5:createFromParcel(Parcel source) 方法
    • 6:newArray(int size) 方法
  • 三:Parcelable数据传输和接收
    • 1:数据传输
    • 2:数据接收
    • 3:结果
  • 四:插件简化Parcelable开发
  • 五:总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档