前言
Intent除了来启动activity,发送广播,启动服务等。我们还可以在Intent中添加数据,以达到在两个activity传递数据的作用。
我们可以这样传递一些简单的数据:
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("username", "zhangsan");
intent.putExtra("password", "123456");
startActivity(intent);
那么在SecondActivity.java中,接可以这样获取:
String username = getIntent().getStringExtra("username");
String password = getIntent().getIntExtra("password");
但是如何传递对象呢?
这里有两种方式:
- Serializable
- Parcelable
第一种:Serializable方式
Serializable是序列化的意思,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。至于序列化的方法也很简单,只需要让一个类去实现 Serializable 这个接口就可以了。
比如说下面的Person类:
public class Person implements Serializable {
public String userName;
public String passWord;
// get and set method ...
}
接下来,我们在FirstActivity中传递这个对象到SecondActivity中:
Person person = new Person();
person.setUserName("zhangsan");
person.setPassWord("123456");
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtral("person", intent);
startActivity(intent);
在SecondActivity.java中获取:
Person person = (Person) getIntent().getSerializableExtra("person");
第二种:Parcelable方式
Parcelable方式能达到Serializable方式相同的效果。
下面我们来看一下 Parcelable 的实现方式,修改 Person 中的代码,如下所示:
public class Person implements Parcelable {
public String userName;
public String passWord;
// get and set method ...
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(username); // 写出username
dest.writestring(password); // 写出password
}
public static final Parcelable.Creator<Person> CREATOR = new Parcelable.
Creator<Person>() {
@Override
public Person createFromParcel(Parcel source) {
Person person = new Person();
person.username = source.readString(); // 读取username
person.password = source.readString(); // 读取password
return person;
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
}
Parcelable的实现方式要稍微复杂一些,实现接口后,重写两个方法:
- describeContents(); 这个方法不需要管,直接返回0即可
- writeToParcel(Parcel dest, int flags); 此方法中我们需要调用 Parcel的 writeXxx()方法将 Person 类中的字段一一写出
Tips:在writeToParcel()方法中将对象相关字段按照相应的数据类型写入,但是提供的写入方法中却没有写入boolean类型的方式:
这里提供一种解决方式->
写 : dest.writeByte((byte) (yourBoolean ? 1 : 0));
读 : yourBoolean = source.readByte() == 1;注意:字符串型数据就调用 writeString()方法,整型数据就调用 writeInt()方法,以此类推。
除此之外,我们还必须在 Person 类中提供一个名为 CREATOR 的常量,这里创建了Parcelable.Creator 接口的一个实现,并将泛型指定为 Person。接着需要重写 createFromParcel()和 newArray()这两个方法,在 createFromParcel()方法中我们要去读取刚才写出的 name 和 age字段,并创建一个 Person 对象进行返回,其中 name 和 age 都是调用 Parcel 的 readXxx()方法读取到的,注意这里读取的顺序一定要和刚才写出的顺序完全相同。而 newArray()方法中的实现就简单多了,只需要 new 出一个 Person 数组,并使用方法中传入的 size 作为数组大小就可以了。
接下来,在FirstActivity中传递的方式不变,在SecondActivity中获取的方式要改变一下:
Person person = (Person) getIntent().getParcelableExtra("person");
总结
虽然两种方式都能达到相同效果,但是我们还是建议使用Parcelable方式来传递数据,原因是,Serializable方式会将整个对象进行序列化,效率方面要低,从事终端开发,对效率要求还是比较高的。