安卓序列化物件--包括序列化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
implements
Serializable {
private
static
final
long
serialVersionUID = 21455356667888L;//記得這裡要填上
private
String mName;
private
int
mPrice;
private boolean flag;
}
那麼在intent傳遞的時候,程式碼如下:
Book book =
new
Book();
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
implements
Parcelable {
public String name; public int money; public boolean flag;
@Override
public
int
describeContents() {
return
0
;
}
@Override
public
void
writeToParcel(Parcel dest,
int
flags) {
dest.writeString(name); dest.writeInt(money); dest.writeByte((byte)(flag ? 1:0));//if myBoolean == true, byte == 1
}
public
static
final
Parcelable.Creator<Person> CREATOR =
new
Creator<Person>() {
@Override
public
Person createFromParcel(Parcel source) {
//這裡一定要注意,這裡的順序一定要不要搞錯了.不然取不出來值,為這個我頭痛了二個小時 //如果有boolean型別的資料,在這裡就得傳為數值型,然後再轉回去 Personperson
= new Person();person
.name = source.readString();person
.money = source.readInt();person
.flag = source.readByte() != 0; //myBoolean == true if byte != 0
return
person;
}
//供反序列化本類陣列時呼叫的
@Override
public
Person[] newArray(
int
size) {
return
new
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
);