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 类型扩展详解 ------ 新手使用指南
相关推荐
mykrecording1 小时前
launch Activity流程
android·app
云起SAAS2 小时前
菜谱食谱抖音快手微信小程序看广告流量主开源
微信小程序·小程序·ai编程·看广告变现轻·菜谱食谱
不知名的前端专家2 小时前
uniapp 安卓FTP上传下载操作原生插件
android·uni-app
ClassOps3 小时前
Android Studio Logcat中 杀死应用
android·android studio·logcat
lagelangri6663 小时前
MySql的存储过程以及JDBC实战
android·数据库·mysql
指针不南3 小时前
Android Studio | 设置国内代理(SDK 设置国内代理(阿里云镜像))
android·阿里云·android studio
shadowcz0073 小时前
Claude 4.5用于AI编程-前端开发的Prompt工程#最佳实践指南
prompt·ai编程
Knock man4 小时前
Android AIDL通信案例
android
2501_916013749 小时前
iOS 26 系统流畅度检测 从视觉特效到帧率稳定的实战策略
android·macos·ios·小程序·uni-app·cocoa·iphone
秋月的私语9 小时前
如何快速将当前的c#工程发布成单文件
android·java·c#