安卓开发之使用Intent传递对象
Intent还是很有用的一个好东西,可以帮我们启动活动、发送广播、启动服务等等。但是它并不是这么简单,它能耍一耍传递数据的花活。
传递简单的数据
比如说,我们可以在某一个活动中定义这样一个intent:
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("a string", "hello world");
intent.putExtra("a int", 123);
startActivity(intent);
然后,我们可以在第二个活动这样获取上例中的数据:
getIntent().getStringExtra("a string");
getIntent().getIntExtra("a int", 0);
可以看到,数据传递还是很简单的,也很容易理解,需要说明的时,putExtra函数的参数是以键值对的方式给出的,getIntExtra函数的第二个参数是默认值,也就是不能成功获取数据的时候的函数返回值,可以随便写啦。但是嘞,这种方法传递的数据类型还是很有限的,当我么需要传递自定义的数据类型的时候,就会很捉急!燃鹅不用担心,我们还有更多的技巧用来传递数据。
Serializable方式
Serializable即序列化,意思就是将一个对象转换成可存储或者可传输的状态。具体的实现方法是让一个类去实现Serializable这个接口。
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;
}
}
现在,我们再往intent中加入数据的时候就可以这样写了:
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);
数据的获取也就不一样咯:
Person person = (Person) getIntent().getSerializableExtra("person data");
这里调用了getSerializableExtra()函数来获取通过参数传递过来的序列化对象,接着再将它向下转型为Person对象,这样我们就成功实现了利用intent来传递对象的功能啦!
Parcelable方式
Parcelable的实现原理是将一个完整的对象进行分解,而分解之后的每一部分都是Intent可以传递的数据类型。代码实现:
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];
}
};
}
复杂……好烦……是不是……但是!这种方法的效率会比前者更高,因为它没有将整个对象序列化。所以,还是推荐使用这种方法。
首先,也是实现接口,然后重写了两个函数describeContents()和writeToParcel()。尤其是第二个函数,要在这里面将类的各个字段一一写出。我们还必须在Person类中提供一个名为CREATE的常量。数据的加载方式不变,具体的获取数据的方法基本一致,只不过换了个名字:
Person person = (Person) getIntent().getParcelableExtra("person data");