【Android】使用 Intent 传递对象的两种序列化方式

【Android】使用 Intent 传递对象的两种序列化方式

Android 中我们经常使用 Intent 在不同的组件之间传递数据,比如从一个 Activity 跳转到另一个 Activity 时传递参数。对于简单的数据(如 intString 等),使用 putExtra 非常方便。但如果我们要传递 自定义对象,就需要使用更复杂的方式。

方式一:Serializable

1. 定义对象类

java 复制代码
import java.io.Serializable;

public class User implements Serializable {
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Getter / Setter 省略
}

2. 发送方 Activity

java 复制代码
Intent intent = new Intent(this, SecondActivity.class);
User user = new User("张三", 20);
intent.putExtra("user", user);
startActivity(intent);

3. 接收方 Activity

java 复制代码
User user = (User) getIntent().getSerializableExtra("user");

这里调用了 getSerializableExtra() 方法来获取通过参数传递过来的序列化对象,接着再将它向下转型成 Person 对象,这样我们就成功实现了使用 Intent 来传递对象的功能了。

原理 :通过 Java 的 ObjectOutputStream 将对象转为字节流,反序列化时用 ObjectInputStream 重建对象。

优点

  • 实现简单,只需实现 Serializable 接口。

缺点

  • 性能较差。
  • 不适合频繁传输或大对象。
  • 不能控制序列化过程,不安全。

方式二:Parcelable

Android 官方推荐使用 Parcelable,因为它序列化/反序列化速度更快,内存使用更高效。

1. 定义对象类

java 复制代码
import android.os.Parcel;
import android.os.Parcelable;

public class User implements Parcelable {
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    protected User(Parcel in) {
        name = in.readString();
        age = in.readInt();
    }

    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel in) {
            return new User(in);
        }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
    }

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

    // Getter / Setter 可选
}

Parcelable 的实现方式要复杂一些,首先让 User 类实现了 Parcelable 接口,这样就必须重写 describeContents()writeToParcel() 这两个方法,其中 describeContents() 方法直接返回0就可以了,而 writeToParcel() 方法中我们需要调用 Parcel 的 writeXxx() 方法,将 Person 类中的字段一一写出。注意,字符串型数据就调用 writestring() 方法,整型数据就调用 writeInt() 方法,以此类推。

关键注意事项

  • createFromParcel() 方法中,字段读取顺序( readString()readInt() )必须严格匹配 writeToParcel() 方法中的字段写入顺序。

  • newArray() 方法只需简单创建对应大小的数组。

2. 发送方 Activity

java 复制代码
Intent intent = new Intent(this, SecondActivity.class);
User user = new User("李四", 25);
intent.putExtra("user", user);
startActivity(intent);

3. 接收方 Activity

java 复制代码
User user = getIntent().getParcelableExtra("user");

原理 :通过 Parcel 内存容器直接操作二进制数据,避免反射开销。

优点

  • 性能优于 Serializable,可自定义序列化过程。

缺点

  • 编写代码繁琐,对于嵌套对象或集合,需要额外实现嵌套类的 Parcelable

两种方式对比

Serializable Parcelable
实现复杂度 简单(只需 implements) 较高(手动写入字段)
序列化速度 快(无反射)
GC/内存开销 大(使用反射) 小(结构紧凑)
是否可控 不可控 精确控制
嵌套支持 自动递归序列化 手动嵌套写入/读取
集合支持 支持所有实现 Serializable 的集合 需使用专门 API,如 writeTypedList

虽然 Serializable 使用简单,但在 Android 中,Parcelable 是更推荐的选择,尤其是在性能敏感或大对象频繁传输的场景。对于有嵌套对象或集合的类:

  • Serializable 可以省心地一键传输;
  • Parcelable 则更灵活、更高效,但需要写更多代码。
相关推荐
Wang's Blog1 分钟前
PostgreSQL笔记34:索引优化策略全景解析——从B-tree到HOT的核心原理与实践
数据库·笔记·postgresql
金字塔頂の蝸牛6 分钟前
商务日语口语实用手册
笔记·学习笔记·日语·外语
m0_5873830013 分钟前
社区家政系统开发实战:从需求分析到上线部署全指南
java·spring boot·spring·需求分析
凤山老林17 分钟前
动态 i18n 体系落地:Spring Boot 多租户热加载与前后端协同实践
java·spring boot·后端·i18n
小雪崩29 分钟前
嵌入式学习 day25:哈希表及排序与查找
linux·c语言·数据结构·学习·排序算法
白露与泡影1 小时前
解密 Pi 的 Harness 工程:Agent 会话如何实现持久化与恢复
java·人工智能·算法
HwJack201 小时前
UIAbility 生命周期全链路:从冷启动到热启动的实战笔记
笔记·华为·harmonyos
九硕智慧建筑一体化厂家1 小时前
直流智能照明|全场景节能升级!打造安全低碳的智慧建筑光环境
运维·笔记·安全·智慧城市
yiqiefeimeng1 小时前
C语言指针难倒90%人?买房比喻让你瞬间开窍
c语言·学习·编程·指针·比喻
又见情义1 小时前
RK3568 Android 13 驱动适配实战:从零开始让SDK在自己的板子上跑起来
android·arm开发·驱动开发