為什么我們需要序列化
序列化的原因基本可以歸納為以下三種情況:
1.永久性保存對象,保存對象的字節序列到本地文件中;
2.對象在網絡中傳遞;
3.對象在IPC間傳遞。
android序列化方式
- Java 通過實現Serializable的接口來實現序列化。
- Android 原生序列化接口中Parcelable接口。
兩者之間的區別
- 內存序列化 Serializable在序列化的時候會產生大量的碎片的臨時變量,從而引起頻繁的內存GC,相比Parcelable 更適合在內存中作為序列化傳輸數據。
- 網絡序列化以及硬盤序列化 不能能使用在要將數據存儲在磁盤上的情況(如:永久性保存對象,保存對象的字節序列到本地文件中),因為Parcel本質上為了更好的實現對象在IPC間傳遞,并不是一個通用的序列化機制,當改變任何Parcel中數據的底層實現都可能導致之前的數據不可讀取,所以此時還是建議使用Serializable 。
Serializable實現以及使用
android使用Serializable來序列化非常的簡單, 只需要實現Serializable接口, 剩下系統變自動會完成。
唯一需要注意的是serialVersionUID 序列化的版本編號,Java的序列化機制是通過在運行時判斷類的serialVersionUID來驗證版本一致性的。在進行反序列化時,JVM會把傳來的字節流中的serialVersionUID與本地相應實體(類)的serialVersionUID進行比較,如果相同就認為是一致的,可以進行反序列化,否則就會出現序列化版本不一致的異常。
Parcelable實現以及使用
相比Serializable來說 Parcelable的實現比較的復雜。
- 實現Parcelable接口
- 重寫writeToParcel方法,將你的對象序列化為一個Parcel對象,即:將類的數據寫入外部提供的Parcel中,打包需要傳遞的數據到Parcel容器保存,以便從Parcel容器獲取數據。
- 重寫describeContents方法,內容接口描述,默認返回0即可。
- 實例化靜態內部對象CREATOR實現接口Parcelable.Creator 。
- 注意:若將Parcel看成是一個流,則先通過writeToParcel把對象寫到流里面,再通過createFromParcel從流里讀取對象,因此類實現的寫入順序和讀出順序必須一致。*
FAQ :當項目中使用的時候 出現的一個錯誤: 傳遞對象列表,具體代碼如下: 需要注意的是,若List personList = new ArrayList();則會報錯,因為下面調用的putParcelableArrayList()函數其中一個參數的類型為ArrayList。 所以變量應該聲明為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;
}