Android Serializable與Parcelable 分析對比整理

1.Serializable接口

序列化與反序列化就是JAVA對象與一串字節流之間的相互轉換, 我們在程序中創建的JAVA對象只存在于JVM中, 當程序退出時, 這些對象也就消失了, 而序列化正是為了將這些對象保存起來以僅將來使用,也可以將已經序列化的對象傳送給其他JVM來使用,這些序列化的字節流是于JVM無關的, 也就是說一個JVM序列化的對象可以在另一個JVM中反序列化.
序列化分為兩大部分:序列化和反序列化。 序列化是這個過程的第一部分,將數據分解成字節流,以便存儲在文件中或在網絡上傳輸。 反序列化就是打開字節流并重構對象。 對象序列化不僅要將基本數據類型轉換成字節表示,有時還要恢復數據。 恢復數據要求有恢復數據的對象實例。 ObjectOutputStream中的序列化過程與字節流連接,包括對象類型和版本信息。 反序列化時,JVM用頭信息生成對象實例,然后將對象字節流中的數據復制到對象數據成員中。
Java的對象序列化只要對象實現了Serializable接口
這個接口只是一個標記接口,不包含任何的方法,

使用JAVA提供的序列化機制有以下兩條需要遵守的條件:

1.該類必須直接實現java.io.Serializable接口或者間接從其繼承樹中實現該接口(也就是他的某個父類實現了這個接口);
2.對于該類的所有無法序列化的屬性(本文指字段field, 而不是嚴格意義上的屬性property, 下同)必須使用transient修飾.
補充說明:
從其繼承樹中實現Serializable接口指的是該類的某個父類實現了這個接口, 要注意的是Object類并沒有實現該接口, 也就是說默認的情況下我們定義的類是不支持序列化的, 而JDK提供的某些類如String, 數組等實現了該接口;
無法序列化的屬性包括兩種:一種是主觀上不想保存的屬性, 如動態生成的屬性或者考慮到性能上的要求不準備保存的屬性; 另一種是由于該屬性的類型沒有實現序列化而無法保存的屬性, 如Thread類型的屬性;
安全方面的原因,比如一個對象擁有private,public等field,對于一個要傳輸的對象,比如寫到文件,或者進行rmi傳輸等等,在序列化進行傳輸的過程中,這個對象的private等域是不受保護的。

transient

變量修飾符,如果用transient聲明一個實例變量,當對象存儲時,它的值不需要維持。
換句話來說就是,用transient關鍵字標記的成員變量不參與序列化過程。Serializable序列化不保存靜態變量,可以使用Transient關鍵字對部分字段不進行序列化,也可以覆蓋writeObject、readObject方法以實現序列化過程自定義。

場景:某個類的有些屬性需要序列化,而其他屬性不需要被序列化,打個比方,如果一個用戶有一些敏感信息(如密碼,銀行卡號等),為了安全起見,不希望在網絡操作(主要涉及到序列化操作,本地序列化緩存也適用)中被傳輸,這些信息對應的變量就可以加上transient關鍵字。換句話說,這個字段的生命周期僅存于調用者的內存中而不會寫到磁盤里持久化。

序列化過程

如果我們想要序列化一個對象,首先要創建某些OutputStream(如FileOutputStream、ByteArrayOutputStream等),然后將這些OutputStream封裝在一個ObjectOutputStream中。這時候,只需要調用writeObject()方法就可以將對象序列化,并將其發送給OutputStream(記住:對象的序列化是基于字節的,不能使用Reader和Writer等基于字符的層次結構)。而飯序列的過程(即將一個序列還原成為一個對象),需要將一個InputStream(如FileInputstream、ByteArrayInputStream等)封裝在ObjectInputStream內,然后調用readObject()即可。
序列化算法一般會按步驟做如下事情:

◆將對象實例相關的類元數據輸出。
◆遞歸地輸出類的超類描述直到不再有超類。
◆類元數據完了以后,開始從最頂層的超類開始輸出對象實例的實際數據值。
◆從上至下遞歸輸出實例的數據

對象序列化過程不僅僅保存單個對象,還能追蹤對象內所包含的所有引用,并保存那些對象(這些對象也需實現了Serializable接口)
任何類型只要實現了Serializable接口,就可以被保存到文件中,或者作為數據流通過網絡發送到別的地方。

反序列化

序列化機制并不要求該類具有一個無參的構造方法, 因為在反序列化的過程中實際上是去其繼承樹上找到一個沒有實現Serializable接口的父類(最終會找到Object), 然后構造該類的對象, 再逐層往下的去設置各個可以反序列化的屬性(也就是沒有被transient修飾的非靜態屬性).

在反序列的JVM上必須能夠找到該類(有可能序列化和反序列化并不是在同一個JVM上進行的), 否則就會拋出ClassNotFoundException;
由于ObjectInputStream.readObject()方法可以反序列化任何類的對象, 所以其返回類型為Object, 我們需要將其強轉成具體的類;
如何對不滿足序列化機制的兩個要求的類進行序列化, 則會拋出NotSerializableException;
如果JVM發現序列化與反序列化的類文件"不相同", 則會拋出InvalidClassException.

Parcelable 實現過程

1.實現Parcelable接口

2.實現接口中的兩個方法

public int describeContents();
public void writeToParcel(Parcel dest, int flags);

第一個方法是內容接口描述,默認返回0就可以了
第二個方法是將我們的對象序列化一個Parcel對象,也就是將我們的對象存入Parcel中 .

3.實例化靜態內部對象CREATOR實現接口Parcelable.Creator,實例化CREATOR時要實現其中的兩個方法,其中createFromParcel的功能就是從Parcel中讀取我們的對象。

對比分析

Serializable是Java的實現方式,可能會頻繁的IO操作,所以消耗比較大,但是實現方式簡單 Parcelable是Android提供的方式,效率比較高,但是實現起來復雜一些Parcelable的性能比Serializable好,在內存開銷方面較小,所以在內存間數據傳輸時推薦使用Parcelable,如activity間傳輸數據,而Serializable可將數據持久化方便保存,所以在需要保存或網絡傳輸數據時選擇Serializable.

在讀寫數據的時候,Parcelable是在內存中直接進行讀寫,而Serializable是通過使用IO流的形式將數據讀寫入在硬盤上.
Serializable在序列化操作的時候會產生大量的臨時變量,(原因是使用了反射機制)從而可能導致GC的頻繁調用。
Parcelable是以Ibinder作為信息載體的.在內存上的開銷比較小,因此在內存之間進行數據傳遞的時候,使用Parcelable,

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,565評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,115評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,577評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,514評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,234評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,621評論 1 326
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,641評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,822評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,380評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,128評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,319評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,879評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,548評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,970評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,229評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,048評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,285評論 2 376

推薦閱讀更多精彩內容