Parcelable 和 Serializable 的区别详解 —— 新手指南

在 Android 开发中,ParcelableSerializable 是两种用于对象序列化的接口,但它们在设计目标、性能和使用场景上有显著差异。以下是它们的详细对比:

一、核心区别

特性 Parcelable Serializable
所属平台 Android 特有 Java 标准
设计目标 内存中的高效序列化(IPC 通信) 通用对象序列化(存储/网络传输)
实现复杂度 需手动实现 writeToParcel()CREATOR 仅需声明接口(可自动序列化)
性能 (显式操作,无反射) (依赖反射,生成临时对象)
适用场景 Activity/Fragment 间传递数据 持久化存储(如文件、数据库)或网络传输
版本兼容性 需要手动处理字段顺序 依赖 serialVersionUID 控制版本

二、使用场景

  • 选择 Parcelable

    • 高频数据传输:如 Activity 之间传递复杂对象。
    • 性能敏感场景:避免因序列化导致界面卡顿(如大量数据传递)。
    • Android 组件通信:Intent 中传递自定义对象。
  • 选择 Serializable

    • 数据持久化:将对象保存到文件或数据库中。
    • 网络传输:通过 HTTP 或 Socket 发送对象。
    • 简单场景:快速实现序列化,无需处理复杂逻辑。

三、注意事项

Parcelable

  1. 字段顺序必须一致
    writeToParcel()CREATOR 中读写字段的顺序需严格一致,否则数据会错乱。
  2. 代码维护成本高
    手动实现序列化逻辑,对象结构变化时需同步修改代码。
  3. 工具辅助
    使用 Android Studio 插件(如 Parcelable Code Generator )或第三方库(如 Parceler)自动生成代码。

Serializable

  1. 版本兼容性问题
    必须显式声明 private static final long serialVersionUID,否则类修改后可能导致反序列化失败。
  2. 性能陷阱
    避免序列化大型对象或频繁调用,可能引发 GC 卡顿或 ANR。
  3. 安全风险
    反序列化时可能执行恶意代码(需谨慎处理外部数据)。

四、如何选择?

  • 优先 Parcelable

    • 所有 Android 组件间传递数据的场景。
    • 对象需要高频传递或数据量较大(如 Bitmap 包装类)。
  • 优先 Serializable

    • 需要将对象存储到文件或数据库。
    • 与后端通信时传输数据(需确保双方使用相同序列化协议)。
    • 快速原型开发,对性能不敏感。

五、示例代码

1. Parcelable 实现

kotlin 复制代码
data class User(
    val id: Int,
    val name: String,
    val email: String
) : Parcelable {

    // 从 Parcel 中读取字段(顺序必须与 writeToParcel 一致)
    constructor(parcel: Parcel) : this(
        parcel.readInt(),
        parcel.readString() ?: "",
        parcel.readString() ?: ""
    )

    // 将字段写入 Parcel
    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeInt(id)
        parcel.writeString(name)
        parcel.writeString(email)
    }

    override fun describeContents(): Int = 0

    companion object CREATOR : Parcelable.Creator<User> {
        override fun createFromParcel(parcel: Parcel): User = User(parcel)
        override fun newArray(size: Int): Array<User?> = arrayOfNulls(size)
    }
}

// 传递数据
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("user", user)
startActivity(intent)

2. Serializable 实现

kotlin 复制代码
data class User(
    val id: Int,
    val name: String,
    val email: String
) : Serializable {
    // 显式声明 serialVersionUID(需通过工具生成或手动维护)
    companion object {
        private const val serialVersionUID: Long = 123456789L
    }
}

// 存储到文件
val user = User(1, "Alice", "alice@example.com")
val file = File(context.filesDir, "user.dat")
ObjectOutputStream(FileOutputStream(file)).use { it.writeObject(user) }

// 从文件加载
val loadedUser = ObjectInputStream(FileInputStream(file)).readObject() as User

六、高级优化

  • Parcelable 性能优化

    • 使用 @Parcelize 注解(需引入 kotlin-parcelize 插件)自动生成代码。

      kotlin 复制代码
      @Parcelize
      data class User(val id: Int, val name: String) : Parcelable
  • 替代方案

    • JSON/Protobuf:网络传输时更高效。
    • Room 或 Realm:直接存储对象到数据库,无需手动序列化。

七、总结

  • Parcelable:是 Android 平台的高性能 IPC 通信首选,适合内存中数据传输。
  • Serializable: 适用于持久化存储和兼容 Java 生态的场景,但需注意性能问题。
  • 按需选择:结合具体场景,平衡性能、开发效率和可维护性。

更多分享

  1. Android跨进程通信中的关键字详解:in、out、inout、oneway
  2. Android Executor 与 Executors 详解 ------ 新手指南
  3. Kotlin 委托与扩展函数------新手入门
  4. Kotlin 作用域函数(let、run、with、apply、also)的使用指南
  5. 一文带你吃透Kotlin中 lateinit 和 by lazy 的区别和用法
  6. Kotlin 扩展方法(Extension Functions)使用详解
  7. Kotlin 中 == 和 === 的区别
  8. Kotlin 操作符与集合/数组方法详解------新手指南
  9. Kotlin 中 reified 配合 inline 不再被类型擦除蒙蔽双眼
  10. Kotlin Result 类型扩展详解 ------ 新手使用指南
相关推荐
hjlgs2 小时前
framework修改快速验证
android
游戏开发爱好者82 小时前
iOS 开发者的安全加固工具,从源码到成品 IPA 的多层防护体系实践
android·安全·ios·小程序·uni-app·cocoa·iphone
安卓理事人3 小时前
安卓内存泄露排查LeakCanary
android
oden3 小时前
Prompt工程实战:让AI输出质量提升10倍的技巧
aigc·ai编程
秃了也弱了。4 小时前
MySQL空间函数详解,MySQL记录经纬度并进行计算
android·数据库·mysql
.豆鲨包5 小时前
【Android】Binder机制浅析
android·binder
oden5 小时前
Claude用不好浪费钱?10个高级技巧让效率翻3倍
aigc·ai编程·claude
Nerve6 小时前
GooglePay: API 文档
android·google
Nerve7 小时前
GooglePay: 订阅商品购买流程
android·google
summerkissyou19877 小时前
Audio-触摸音-播放流程
android