Android中Serializable和Parcelable的用法及區(qū)別
第一點(diǎn)薄啥,解釋什么是序列化茵典。
序列化 (Serialization)是將對(duì)象的狀態(tài)信息轉(zhuǎn)換為可以存儲(chǔ)或傳輸?shù)男问降倪^(guò)程。
在序列化期間,對(duì)象將其當(dāng)前狀態(tài)寫入到Ram 或者是rom,也就是臨時(shí)或持久性存儲(chǔ)區(qū)。
以后投蝉,可以通過(guò)從存儲(chǔ)區(qū)中讀取對(duì)象的狀態(tài),重新創(chuàng)建該對(duì)象征堪,這個(gè)就是反序列化瘩缆。
Android中用到的序列化有兩種方法,第一種是Serializable佃蚜,第二種是Parcelable庸娱。
Serializable
Serializable 是可串行化,也就是序列化的意思谐算。Serializable 是java序列化的一種方式熟尉,在java里面也是一個(gè)接口。源碼里面這個(gè)接口里啥也沒(méi)有洲脂,如果一個(gè)接口里面什么內(nèi)容都沒(méi)有斤儿,那么這個(gè)接口是一個(gè)標(biāo)識(shí)接口就相當(dāng)于告訴JVM,需要你幫我序列化這個(gè)類恐锦。
怎么去實(shí)現(xiàn)它呢往果?就把我們要序列化的類繼承這個(gè)接口就行了,最好再指定一個(gè)
serialVersionUid
這個(gè)serialVersionUID是用來(lái)輔助對(duì)象的序列化與反序列化的一铅,原則上序列化后的數(shù)據(jù)當(dāng)中的serialVersionUID與當(dāng)前類當(dāng)中的serialVersionUID一致陕贮,那么該對(duì)象才能被反序列化成功。這個(gè)serialVersionUID的詳細(xì)的工作機(jī)制是:在序列化的時(shí)候系統(tǒng)將serialVersionUID寫入到序列化的文件中去潘飘,當(dāng)反序列化的時(shí)候系統(tǒng)會(huì)先去檢測(cè)文件中的serialVersionUID是否跟當(dāng)前的文件的serialVersionUID是否一致肮之,如果一直則反序列化成功,否則就說(shuō)明當(dāng)前類跟序列化后的類發(fā)生了變化卜录,比如是成員變量的數(shù)量或者是類型發(fā)生了變化局骤,那么在反序列化時(shí)就會(huì)發(fā)生crash,并且回報(bào)出錯(cuò)誤
也可以不指定~不指定就會(huì)隨機(jī)分配一個(gè)暴凑。
兩者最大的區(qū)別在于存儲(chǔ)媒介的不同,Serializable使用IO讀寫存儲(chǔ)在硬盤上赘来,而Parcelable是直接在內(nèi)存中讀寫现喳,很明顯內(nèi)存的讀寫速度通常大于IO讀寫凯傲,所以在Android中通常優(yōu)先選擇Parcelable。
Serializable 使用硬盤存儲(chǔ)的性質(zhì)也就注定了它一般用于異地網(wǎng)絡(luò)傳輸嗦篱。
序列化過(guò)程使用了反射技術(shù)冰单,并且期間產(chǎn)生臨時(shí)對(duì)象。優(yōu)點(diǎn)代碼少灸促。是利用反射創(chuàng)建了一個(gè)對(duì)象诫欠,調(diào)用該類的第一個(gè)非Serializable類型的父類的無(wú)參構(gòu)造方法。所以這就是為什么通過(guò)反序列化創(chuàng)建對(duì)象的時(shí)候浴栽,并不會(huì)執(zhí)行被序列化對(duì)象的構(gòu)造方法荒叼。對(duì)于實(shí)現(xiàn)Serializable接口的類,并不要求該類具有一個(gè)無(wú)參的構(gòu)造方法, 因?yàn)樵诜葱蛄谢倪^(guò)程中實(shí)際上是去其繼承樹上找到一個(gè)沒(méi)有實(shí)現(xiàn)Serializable接口的父類(最終會(huì)找到Object)典鸡,然后構(gòu)造該類的對(duì)象被廓,再逐層往下的去設(shè)置各個(gè)可以反序列化的屬性(也就是沒(méi)有被transient修飾的非靜態(tài)屬性)。
Parcel
簡(jiǎn)單來(lái)說(shuō)萝玷,Parcel提供了一套機(jī)制嫁乘,可以將序列化之后的數(shù)據(jù)寫入到一個(gè)共享內(nèi)存中,其他進(jìn)程通過(guò)Parcel可以從這塊共享內(nèi)存中讀出字節(jié)流球碉,并反序列化成對(duì)象蜓斧。
實(shí)現(xiàn)方法:繼承Parcelable,重寫3個(gè)方法睁冬,一個(gè)靜態(tài)對(duì)象
構(gòu)造方法-根據(jù)parcel 構(gòu)造出一個(gè)對(duì)象
重寫3個(gè)方法
createFromParcel(Parcel parcel)
writeToParcel(Parcel parcel)
newArray(int size)
靜態(tài)內(nèi)部類 CREATOR挎春,用于反序列化調(diào)構(gòu)造出對(duì)象
本質(zhì)上就是把對(duì)象的基本數(shù)據(jù)按照開發(fā)者定義的順序?qū)懭胍粋€(gè)parcel 中,接收端再按照這個(gè)順序讀取出來(lái)痴突,組合成一個(gè)對(duì)象~
優(yōu)點(diǎn):內(nèi)存中實(shí)現(xiàn)搂蜓,快!A勺啊帮碰!不會(huì)有大量臨時(shí)變量