1. 程式人生 > >安卓序列化物件--包括序列化boolean型變數

安卓序列化物件--包括序列化boolean型變數

安卓序列化有兩種方式,分別是實現Serializable介面和Parcelable介面,其中Serializable介面是來自Java中的序列化介面,而Parcelable是Android自帶的序列化介面。

上述的兩種序列化介面都有各自不同的優缺點,我們在實際使用時需根據不同情況而定。

1.Serializable在序列化的時候會產生大量的臨時變數,從而引起頻繁的GC,而相比之下Parcelable的效能更高(畢竟是Android自帶的),所以當在使用記憶體時(如:序列化物件在網路中傳遞物件或序列化在程序間傳遞物件),更推薦使用Parcelable介面。

2.但Parcelable有個明顯的缺點:不能能使用在要將資料儲存在磁碟上的情況(如:永久性儲存物件,儲存物件的位元組序列到本地檔案中),因為Parcel本質上為了更好的實現物件在IPC間傳遞,並不是一個通用的序列化機制,當改變任何Parcel中資料的底層實現都可能導致之前的資料不可讀取,所以此時還是建議使用Serializable 。

Serializable介面的實現及使用:

Serializable的介面實現很簡單,只需讓需要序列化的類繼承Serializable 即可,系統會自動將其序列化,具體程式碼如下:

public class Book implementsSerializable { privatestatic final long serialVersionUID = 21455356667888L;//記得這裡要填上 privateString mName; privateint mPrice;
  private boolean flag;
 
}

那麼在intent傳遞的時候,程式碼如下:

Book book =

newBook();

book.setmName("王海康"); book.setmPrice("20$"); Intent intent =new Intent(this, BookTest.class); Bundle bundle =new Bundle(); bundle.putSerializable(SER_KEY, book); intent.putExtras(bundle); startActivity(intent); 然後在接受的時候,程式碼如下:

Book mBook = (Book )getIntent().getSerializableExtra(SER_KEY);

Parcelable介面的實現及使用

實現Parcelable介面主要可以分為一下幾步:
1)implements Parcelable。
2)重寫writeToParcel方法,將你的物件序列化為一個Parcel物件,即:將類的資料寫入外部提供的Parcel中,打包需要傳遞的資料到Parcel容器儲存,以便從Parcel容器獲取資料。
3)重寫describeContents方法,內容介面描述,預設返回0即可。
4)例項化靜態內部物件CREATOR實現介面Parcelable.Creator 。
注意:若將Parcel看成是一個流,則先通過writeToParcel把物件寫到流裡面,再通過createFromParcel從流裡讀取物件,因此類實現的寫入順序和讀出順序必須一致。
具體實現程式碼如下:

public class Person implementsParcelable {
  public String name;
  public int money;
  public boolean flag;
@Override publicint describeContents() { return0; } @Override publicvoid writeToParcel(Parcel dest,int flags) {
    dest.writeString(name);
    dest.writeInt(money);
    dest.writeByte((byte)(flag ? 1:0));//if myBoolean == true, byte == 1
} publicstatic final Parcelable.Creator<Person> CREATOR = newCreator<Person>() { @Override publicPerson createFromParcel(Parcel source) {
//這裡一定要注意,這裡的順序一定要不要搞錯了.不然取不出來值,為這個我頭痛了二個小時
//如果有boolean型別的資料,在這裡就得傳為數值型,然後再轉回去
         Person person= new Person();
         person.name = source.readString();
         person.money = source.readInt();
         person.flag = source.readByte() != 0;     //myBoolean == true if byte != 0
returnperson; } //供反序列化本類陣列時呼叫的 @Override publicPerson[] newArray(intsize) { returnnew Person[size]; } };

然後關於parcel方式的資料傳遞和接受,其實和上面介紹的Serial方式是差不多的,就不介紹了。

2)下面介紹下如何傳遞一個列表物件(List<Person>):前提是集合中的物件必須實現了Parcel規則

// 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;
}

3)最後介紹一個投機取巧的方法:
不用繼承Parcelable或Serializable方法即可實現IPC中物件的傳遞。這種方法的實現原理不是很明白,只知道程式碼中new ArrayList()返回的其實是一個EmptyArray.OBJECT陣列,不過我感覺應該還是系統呼叫Serializable進行序列化的。

//物件List傳遞 public void setObjectMethod(){ ......(省略) ArrayList list =new ArrayList(); //ObjectList為某一物件列表 list.add(ObjectList); bundle.putParcelableArrayList(PAR_LIST_KEY, list); intent.putExtras(bundle); startActivity(intent); } //獲取物件List ArrayList list = bundle.getParcelableArrayList("list"); //強轉成你自己定義的list,這樣ObjectList就是你傳過來的那個list了。 ObjectList= (List<Object>) list.get(0);