Intent傳遞對象的幾種方式
Intent的用法相信你已經比較熟悉了,Intent可以用來啟動Activity,Service等等,同時我們也可以通過Intent來進行傳遞數據,比如以下代碼
Intent intent=new Intent(MainActivity.this,OtherActivity.class);
intent.putExtra("name","lijizhou");
intent.putExtra("age",22);
startActivity(intent);
putExtra雖然可以傳遞大多數的Java數據類型,但還是有限的,當你想傳遞一些自定義對象的時候就會發現無從下手,SO,本篇博文介紹下利用Intent傳遞對象的幾種實現方式,Android中Intent傳遞對象有兩種方式一種是通過實現Serializable接口傳遞對象,一種是通過實現Parcelable接口傳遞對象。Serializable是Java提供的序列化接口,而Parcelable的Android團隊設計的,兩者各有利弊。
下面先介紹Serializable如何使用
Serializable是序列化的意思,表示將一個對象轉換成可儲存或可傳輸的狀態,對象進行Serializable序列化之后就可以通過Intent來進行Activity之間的傳輸了。
比如像下面這樣SerObject類實現Serializable接口 ―- SerObject.java
public class SerObject implements Serializable {
private static final long serialVersionUID=1L;
private String name;
private String age;
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
這里面的serialVersionUID需要注意一下,它的作用是序列化和反序列化時保持版本的兼容性,如果你未指定,運行時也會默認生成,在進行反序列化時只有數據和當前類的serialVersionUID相同是才能夠正常的反序列化,你不指定serialVersionUID一般情況下也不會出問題,但是如果當前類發生了改變例如刪掉了某個成員變量那么當前類的serialVersionUID也會出現改變,之后你對數據進行反序列化就會出現錯誤,這里我指定為1L,L為Long數據類型。
接下來進行對象的傳遞 ,通過Intent攜帶對象數據,來啟動Activity2
SerObject obj=new SerObject();
obj.setName("Serializable");
obj.setAge("22");
Intent mIntent = new Intent(MainActivity.this,Activity2.class);
mIntent.putExtra("Ser",obj);
startActivity(mIntent);
然后在Activity2中讀取數據并打印
SerObject serObject = (SerObject)getIntent().getSerializableExtra("Ser");
Log.i("log",serObject.getName()+"----"+serObject.getAge());
通過Log可以看出成功的將對象傳到了Activity2中
Serializable的使用非常簡單,下面介紹下Parcelable的接口如何實現
Parcelable的序列化原理是將一個對象進行分解,而分解后的每一部分都是Intent所支持的數據類型,因此實現了傳遞對象的功能。
例如下面的 ParObject類
public class ParObject implements Parcelable {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(age);
}
protected ParObject(Parcel in) {
name = in.readString();
age = in.readString();
}
public ParObject(){
}
public static final Creator<ParObject> CREATOR = new Creator<ParObject>() {
@Override
public ParObject createFromParcel(Parcel in) {
return new ParObject(in);
}
@Override
public ParObject[] newArray(int size) {
return new ParObject[size];
}
};
}
可以看到通過Parcelable的實現方式是要復雜很多的,實現Parcelable接口后,需要重寫writeToParcel和describeContents方法,describeContents方法直接返回0就可以了,writeToParcel方法我們需要調用Parcel對象進行數據寫入,例如dest.writeString(name),注意如果name是字符串類型就調用writeString,如果是Int類型就調用writeInt 等等,參考上面代碼。
然后還要在這個類中實現一個名為CREATOR的常量,這里創建了Parcelable.Creator接口的一個實現,并將泛型指定為ParObject(參考上面代碼),然后去重寫createFromParcel和newArray兩個方法,在createFromParcel中通過
Parcel去讀取剛才通過writeToParcel寫入的數據并返回ParObject對象,注意這里的read要和write時候的順序一樣,newArray方法只要new 一個ParObject類的數組,并將size作為數組大小就OK了。
這樣Parcelable的接口實現就OK了,缺點就是數據寫入和讀取等等方法需要手動去實現
,我相信你看的腦袋都大了,當然不能忘了Android Studio這個強大的工具,當你寫好java類并實現了Parcelable 那么后續的writeToParcel createFromParcel newArray等等一系列繁瑣代碼都將自動實現。
類實現Parcelable 然后點到類名上 Alt+enter:
接下來對象的傳遞就簡單多了 和Serializable類似
ParObject obj=new ParObject();
obj.setName("Parcelable");
obj.setAge("22");
Intent mIntent = new Intent(MainActivity.this,Activity2.class);
mIntent.putExtra("Par",obj);
startActivity(mIntent);
然后在Activitry2中接收并打印
ParObject parObject = (ParObject)getIntent().getParcelableExtra("Par");
Log.i("log",parObject.getName()+"----"+parObject.getAge());
對象成功傳遞
Ok 通過Intent傳遞對象的兩種方式介紹完了,Serializable和Parcelable各有利弊,Serializable代碼簡單,但是開銷很大,對androidAPP的性能會有一定的影響,相比,Parcelable使用起來比較麻煩,但是效率比較高,也是android推薦的序列化方式,總結:在內存中的序列化例如Intent傳遞推薦Parcelable,存儲到設備或者進行網絡傳輸推薦Serializable。
源碼下載地址 http://download.csdn.net/detail/leejizhou/9485885
來源:李濟洲