為什么我們需要序列化
序列化的原因基本可以歸納為以下三種情況:
1.永久性保存對象舔示,保存對象的字節(jié)序列到本地文件中彪置;
2.對象在網(wǎng)絡(luò)中傳遞撑螺;
3.對象在IPC間傳遞里伯。
android序列化方式
- Java 通過實現(xiàn)Serializable的接口來實現(xiàn)序列化。
- Android 原生序列化接口中Parcelable接口渤闷。
兩者之間的區(qū)別
- 內(nèi)存序列化 Serializable在序列化的時候會產(chǎn)生大量的碎片的臨時變量疾瓮,從而引起頻繁的內(nèi)存GC,相比Parcelable 更適合在內(nèi)存中作為序列化傳輸數(shù)據(jù)飒箭。
- 網(wǎng)絡(luò)序列化以及硬盤序列化 不能能使用在要將數(shù)據(jù)存儲在磁盤上的情況(如:永久性保存對象狼电,保存對象的字節(jié)序列到本地文件中)蜒灰,因為Parcel本質(zhì)上為了更好的實現(xiàn)對象在IPC間傳遞,并不是一個通用的序列化機(jī)制肩碟,當(dāng)改變?nèi)魏蜳arcel中數(shù)據(jù)的底層實現(xiàn)都可能導(dǎo)致之前的數(shù)據(jù)不可讀取强窖,所以此時還是建議使用Serializable 。
Serializable實現(xiàn)以及使用
android使用Serializable來序列化非常的簡單削祈, 只需要實現(xiàn)Serializable接口翅溺, 剩下系統(tǒng)變自動會完成。
唯一需要注意的是serialVersionUID 序列化的版本編號髓抑,Java的序列化機(jī)制是通過在運行時判斷類的serialVersionUID來驗證版本一致性的咙崎。在進(jìn)行反序列化時,JVM會把傳來的字節(jié)流中的serialVersionUID與本地相應(yīng)實體(類)的serialVersionUID進(jìn)行比較吨拍,如果相同就認(rèn)為是一致的褪猛,可以進(jìn)行反序列化,否則就會出現(xiàn)序列化版本不一致的異常羹饰。
Parcelable實現(xiàn)以及使用
相比Serializable來說 Parcelable的實現(xiàn)比較的復(fù)雜伊滋。
- 實現(xiàn)Parcelable接口
- 重寫writeToParcel方法,將你的對象序列化為一個Parcel對象队秩,即:將類的數(shù)據(jù)寫入外部提供的Parcel中笑旺,打包需要傳遞的數(shù)據(jù)到Parcel容器保存,以便從Parcel容器獲取數(shù)據(jù)刹碾。
- 重寫describeContents方法燥撞,內(nèi)容接口描述,默認(rèn)返回0即可迷帜。
- 實例化靜態(tài)內(nèi)部對象CREATOR實現(xiàn)接口Parcelable.Creator 物舒。
- 注意:若將Parcel看成是一個流,則先通過writeToParcel把對象寫到流里面戏锹,再通過createFromParcel從流里讀取對象冠胯,因此類實現(xiàn)的寫入順序和讀出順序必須一致。*
FAQ :當(dāng)項目中使用的時候 出現(xiàn)的一個錯誤: 傳遞對象列表,具體代碼如下: 需要注意的是锦针,若List personList = new ArrayList();則會報錯荠察,因為下面調(diào)用的putParcelableArrayList()函數(shù)其中一個參數(shù)的類型為ArrayList。 所以變量應(yīng)該聲明為ArrayList即可奈搜。
// parcelable對象List傳遞方法
public void setParcelableListMethod() {
ArrayList<Person> personList = new ArrayList<Person>();
Person person1 = new Person();
person1.setmName("王合づ瑁康");
person1.setmSex("男");
person1.setmAge(45);
personList.add(person1);
Person person2 = new Person();
person2.setmName("薛岳");
person2.setmSex("男");
person2.setmAge(15);
personList.add(person2);
Intent intent = new Intent(this, PersonTest.class);
Bundle bundle = new Bundle();
bundle.putParcelableArrayList(PAR_LIST_KEY, personList);
intent.putExtras(bundle);
startActivity(intent);
}
// parcelable對象獲取方法
public ArrayList<Person> getParcelableMethod(){
ArrayList<Person> mPersonList = getIntent().getParcelableExtra(PAR_LIST_KEY);
return mPersonList;
}