Intent還是很有用的一個(gè)好東西,可以幫我們啟動(dòng)活動(dòng)、發(fā)送廣播、啟動(dòng)服務(wù)等等。但是它并不是這么簡(jiǎn)單,它能耍一耍傳遞數(shù)據(jù)的花活。
傳遞簡(jiǎn)單的數(shù)據(jù)
比如說(shuō),我們可以在某一個(gè)活動(dòng)中定義這樣一個(gè)intent:
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("a string", "hello world");
intent.putExtra("a int", 123);
startActivity(intent);
然后,我們可以在第二個(gè)活動(dòng)這樣獲取上例中的數(shù)據(jù):
getIntent().getStringExtra("a string");
getIntent().getIntExtra("a int", 0);
可以看到,數(shù)據(jù)傳遞還是很簡(jiǎn)單的,也很容易理解,需要說(shuō)明的時(shí),putExtra函數(shù)的參數(shù)是以鍵值對(duì)的方式給出的,getIntExtra函數(shù)的第二個(gè)參數(shù)是默認(rèn)值,也就是不能成功獲取數(shù)據(jù)的時(shí)候的函數(shù)返回值,可以隨便寫啦。但是嘞,這種方法傳遞的數(shù)據(jù)類型還是很有限的,當(dāng)我么需要傳遞自定義的數(shù)據(jù)類型的時(shí)候,就會(huì)很捉急!燃鵝不用擔(dān)心,我們還有更多的技巧用來(lái)傳遞數(shù)據(jù)。
Serializable方式
Serializable即序列化,意思就是將一個(gè)對(duì)象轉(zhuǎn)換成可存儲(chǔ)或者可傳輸?shù)臓顟B(tài)。具體的實(shí)現(xiàn)方法是讓一個(gè)類去實(shí)現(xiàn)Serializable這個(gè)接口。
public class Person implements Serializable {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
現(xiàn)在,我們?cè)偻鵬ntent中加入數(shù)據(jù)的時(shí)候就可以這樣寫了:
Person person = new Person();
person.setName("Tom");
person.setAge(24);
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("person data", person);
startActivity(intent);
數(shù)據(jù)的獲取也就不一樣咯:
Person person = (Person) getIntent().getSerializableExtra("person data");
這里調(diào)用了getSerializableExtra()函數(shù)來(lái)獲取通過(guò)參數(shù)傳遞過(guò)來(lái)的序列化對(duì)象,接著再將它向下轉(zhuǎn)型為Person對(duì)象,這樣我們就成功實(shí)現(xiàn)了利用intent來(lái)傳遞對(duì)象的功能啦!
Parcelable方式
Parcelable的實(shí)現(xiàn)原理是將一個(gè)完整的對(duì)象進(jìn)行分解,而分解之后的每一部分都是Intent可以傳遞的數(shù)據(jù)類型。代碼實(shí)現(xiàn):
public class Person implements Parcelable {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel test, int flags) {
test.writeString(name);
test.writeInt(age);
}
public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
@Override
public Person createFromParcel(Parcel source) {
Person person = new Person();
person.name = source.readString(); //讀取name
person.age = source.readInt(); //讀取age
return person;
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
復(fù)雜……好煩……是不是……但是!這種方法的效率會(huì)比前者更高,因?yàn)樗鼪](méi)有將整個(gè)對(duì)象序列化。所以,還是推薦使用這種方法。
??首先,也是實(shí)現(xiàn)接口,然后重寫了兩個(gè)函數(shù)describeContents()和writeToParcel()。尤其是第二個(gè)函數(shù),要在這里面將類的各個(gè)字段一一寫出。我們還必須在Person類中提供一個(gè)名為CREATE的常量。數(shù)據(jù)的加載方式不變,具體的獲取數(shù)據(jù)的方法基本一致,只不過(guò)換了個(gè)名字:
Person person = (Person) getIntent().getParcelableExtra("person data");