安卓序列化對象--包括序列化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);


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章