在 Android 開發中,對象在進程間傳遞(Intent、Bundle、AIDL、Messenger)或持久化存儲時,必須實現序列化。平台提供兩套機制:Java 標準 Serializable 與 Android 專用 Parcelable。本文從原理、實現複雜度、性能基準、適用場景四個維度全方位對比,助你做出正確選型。
| 維度 | Serializable | Parcelable |
|---|---|---|
| 所屬包 | java.io | android.os |
| 實現方式 | 標記接口,JVM 自動反射序列化 | 需手動實現寫入/讀出邏輯 |
| 存儲介質 | IO 流(硬盤/網絡/內存) | 內存共享 |
| 性能 | 低(大量反射、臨時對象、GC 壓力) | 高(原生內存操作、無反射) |
| 代碼量 | 極少(implements 即可) | 較多(writeToParcel、CREATOR、describeContents) |
| 版本演進 | serialVersionUID 控制 | 手動維護讀寫順序兼容 |
public class User implements Serializable {
private static final long serialVersionUID = 1L; // 強烈建議顯式聲明
private String name;
private int age;
private transient String token; // transient 忽略序列化
// getter/setter
}
public class User implements Parcelable {
private String name;
private int age;
private String token;
public User() {}
protected User(Parcel in) {
name = in.readString();
age = in.readInt();
token = in.readString();
}
@Override public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
dest.writeString(token);
}
@Override public int describeContents() { return 0; }
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]; }
};
}
writeToParcel:按聲明順序寫入字段,基本類型用 writeInt/Long/Float/Double/Boolean/Byte,對象用 writeParcelable/Serializable,集合用 writeList/Map。CREATOR:靜態常量,反序列化工廠,必須命名為 CREATOR。describeContents:通常返回 0;若包含文件描述符返回 CONTENTS_FILE_DESCRIPTOR。對象:含 10 個字段的普通 POJO,序列化/反序列化 10,000 次:
Code → Generate → Parcelable 可一鍵生成模板代碼,再微調即可。
@Parcelize data class User(val name: String, val age: Int, val token: String) : Parcelable
Parcelable.Creator 緩存或拆分傳遞。Parcelable 是 Android 進程間通信的首選,雖然編寫稍繁瑣,但性能優勢壓倒性。現代開發配合 AS 自動生成或 Kotlin @Parcelize,樣板代碼成本極低。Serializable 保留為跨平台序列化或極低頻場景的備選方案。