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", "[email protected]")
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 类型扩展详解 ------ 新手使用指南
相关推荐
_extraordinary_1 小时前
MySQL 事务(二)
android·数据库·mysql
鸿蒙布道师5 小时前
鸿蒙NEXT开发动画案例5
android·ios·华为·harmonyos·鸿蒙系统·arkui·huawei
橙子1991101611 小时前
在 Kotlin 中什么是委托属性,简要说说其使用场景和原理
android·开发语言·kotlin
androidwork11 小时前
Kotlin Android LeakCanary内存泄漏检测实战
android·开发语言·kotlin
笨鸭先游12 小时前
Android Studio的jks文件
android·ide·android studio
gys989512 小时前
android studio开发aar插件,并用uniapp开发APP使用这个aar
android·uni-app·android studio
H3091912 小时前
vue3+dhtmlx-gantt实现甘特图展示
android·javascript·甘特图
像风一样自由12 小时前
【001】renPy android端启动流程分析
android·gitee
千里马学框架14 小时前
重学安卓14/15自由窗口freeform企业实战bug-学员作业
android·framework·bug·systrace·安卓framework开发·安卓窗口系统·自由窗口
xianrenli3819 小时前
android特许权限调试
android