日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android --- Serializable 接口与 Parcelable 接口的使用方法和区别,怎么选择?

發布時間:2025/3/21 Android 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android --- Serializable 接口与 Parcelable 接口的使用方法和区别,怎么选择? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一、前言:
  • 二、Serializable 接口
  • 三、Parcelable 接口
  • 四、兩種接口怎么選擇

一、前言:

本節主要講解 IPC 中的基本概念,Serializable 接口與 Parcelable 接口。
這兩個接口可以完成對象的序列化過程,當我們需要通過 Intent 和 Binder 傳輸數據時就需要使用 Serializable 與 Parcelable 。還有的時候我們需要把對象持久化到存儲設備上或者通過網絡傳輸給其他客戶端,這個時候也需要使用這兩個接口來完成對象的持久化,下面我們一一來介紹。

啥叫對象的持久化?不知道的看下面一句話:

持久化一般指將數據持久化保存,如存到數據庫中或寫到文件中

二、Serializable 接口

Serializable 是 Java所提供的一個序列化接口,這里提到了序列化,那什么叫序列化和反序列化呢?

序列化就是將 Java 對象轉換成二進制文件數據的過程。這樣說可能不是很明白,舉個例子:如果把一個房子比作一個對象,要把這個做房子搬到另外一個地方的話,直接挪動是不現實的,但是可以將房子拆成一個個小零件運輸,到了目的地在組裝成房子,這樣就容易多了,這其中 “拆解” 的過程就是序列化,“重新組裝” 就是反序列化。

說到這里,怎么實現序列化呢?
只需要在類的聲明中指定一個類似下面的標識即可自動實現默認的序列化過程。

private static final long serialVersionUID = 51906712373232662L;

全部代碼:

import java.io.Serializable;public class User implements Serializable {private static final long serialVersionUID = 51906712373232662L;public int userId;public String userName;public boolean isMale;public User(int userId, String userName, boolean isMale) {this.userId = userId;this.userName = userName;this.isMale = isMale;} }

對象的序列化和反序列化只需要采用 ObjectOutputStream 和 ObjectInputStream 即可輕松實現,如下:

// 序列化過程,就是寫的過程User user = new User(0, "Jack", true);ObjectOutputStream out;{try {out = new ObjectOutputStream(new FileOutputStream("user.txt"));out.writeObject(user);out.close();} catch (IOException e) {e.printStackTrace();}}// 反序列化過程,就是讀的過程ObjectInputStream in;User newUser;{try {in = new ObjectInputStream(new FileInputStream("user.txt"));newUser = (User) in.readObject();in.close();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}

現在有個問題,serialVersionUID 是用來輔助序列化和反序列化過程的,原則上序列化后的數據中 serialVersionUID 只有和當前類的 serialVersionUID 相同才能夠正常地被反序列化。不用它行不行,答案:不行。

serialVersionUID 的詳細工作機制是這樣的:序列化的時候系統會把當前的 serialVersionUID 寫入序列化的文件中(也可能是其他中介),當反序列化的時候系統回去檢測文件中的 serialVersionUID ,看它是否和當前類的 serialVersionUID 一致,如果一致就說明序列化類的版本和當前的版本是相同的,這個時候可以成功反序列化;否則就說明當前類和序列化的類相比發生了變化,這個時候是無法反序列化的,會報錯。

再簡單的說就是:反序列化時如果當前類有所改變,比如增加或者刪除了某些成員變量,那么系統就會重新計算當前類的 hash 值并把它賦值給 serialVersionUID ,這個時候當前類的 serialVersionUID 就和序列化的數據中心的 serialVersionUID 不一致,于是反序列化失敗,程序 crash。所以,我們可以明顯感覺到 serialVersionUID 的作用。

Serializable 就介紹到這里了,再加一點比較重要的知識點:靜態成員變量屬于類不屬于對象。所以不會參與序列化的過程,其次使用 transient 關鍵字編輯的成員變量不參與序列化過程。

三、Parcelable 接口

我們在 Android Studio 中寫了一個類 User 實現 Parcelable 接口

public class User implements Parcelable {public int userId;public String userName;public boolean isMale;@Overridepublic int describeContents() {return 0;}@Overridepublic void writeToParcel(Parcel parcel, int i) {} }

這個時候就會爆紅,我們把鼠標放到 User 上面然后按住 "Alt + Enter"鍵會出現下圖的情況,點擊第一個 Add Parcelable Implementation
點擊之后編輯器自動給我們寫了序列化和反序列化過程,非常省事

我們看看全部代碼:

import android.os.Parcel; import android.os.Parcelable;public class User implements Parcelable {public int userId;public String userName;public boolean isMale;protected User(Parcel in) {userId = in.readInt();userName = in.readString();isMale = in.readByte() != 0;}// 反序列化public static final Creator<User> CREATOR = new Creator<User>() {@Overridepublic User createFromParcel(Parcel in) {return new User(in);}@Overridepublic User[] newArray(int size) {return new User[size];}};// 內容描述@Overridepublic int describeContents() {return 0;}// 序列化@Overridepublic void writeToParcel(Parcel parcel, int i) {parcel.writeInt(userId);parcel.writeString(userName);parcel.writeByte((byte) (isMale ? 1 : 0));} }

Parcelable 的方法說明

方法功能標記位
createFromParcel(Parcel in)從序列化后的對象中創建原始對象
newArray(int size)創建指定長度的原始對象數組
User(Parcel in)從序列化后的對象中創建原始對象
writeToParcel (Parcel out, int flags)將當前對象寫入序列化結構中,其中flags標識有兩種值:0或者1(參見右側標記位)。為1時標識當前對象需要作為返回值返回,不能立即釋放資源,幾乎所有情況都為0PARCELABLE_WEITE_RETURN VALUE
describeContents返回當前對象的內容描述。如果含有文件描述符,返回1(參見右側標記位),否則返回0, 幾乎所有情況都返回0CONTENTS_FILE_DESCRIPTOR

四、兩種接口怎么選擇

既然 Parcelable 和 Serializable 都能實現序列化并且都可以用于 Intent 間的數據傳遞,通過二和三我們也知道他們之間的區別了,那么二者該怎么選擇呢?

1.Serializable 是 Java 中的序列化接口,其使用起來開銷比較大,序列化過程有很多 I/O 操作,所以在Java 中我們就采用 Serializable 接口。

2.Parcelable 是 Android 中的序列化方式,因此更適合用在 Android 平臺上,它的缺點就是使用起來比較麻煩,但是它的效率很高,這是 Android 推薦的序列化方式,因此我們要首選 Parcelable。

3.Parcelable 將對象序列化到存儲設備中或者將對象序列化后通過網絡傳輸也都是可以的,但是這個過程會稍微復雜,在 Java 平臺建議用 Serializable,在 Android 平臺建議用 Parcelable 。
部分內容來自安卓開發藝術探索

總結

以上是生活随笔為你收集整理的Android --- Serializable 接口与 Parcelable 接口的使用方法和区别,怎么选择?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。