在Android中,我们会频繁地使用到值传递Intent、Bundle,有时候传递的是int或者String等系统提供的值类型,但有时候要传递自定义的类型,比如用户User。这时我们就要用到Serializable或者Parcelable用于对自定义数据进行序列化
两者区别:
Serializable:是Java提供的序列化接口,所有序列化操作由系统完成,方便但是速度比较慢,效率低。
Parcelable:是Android提供的序列化接口,需要手动完成部分操作(操作详细见下面内容),有些许复杂但是速度快,效率高
实现Parcelable就是为了进行序列化,那么,为什么要序列化?
1)永久性保存对象,保存对象的字节序列到本地文件中;
2)通过序列化对象在网络中传递对象;
3)通过序列化在进程间传递对象。
4)选择序列化方法的原则
注意
1)在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。
2)Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3)Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable 。
4)需要在多个部件(Activity或Service)之间通过Intent传递一些数据,简单类型(如:数字、字符串)的可以直接放入Intent。复杂类型必须实现Parcelable接口。
————————————————
User自定义类代码:
public class User {
private String userName;
private int userAge;
public String getUserName(){
return userName;
}
public void setUserName(String userName){
this.userName = userName;
}
public int getUserAge(){
return userAge;
}
public void setUserAge(int userAge){
this.userAge = userAge;
}
}
————————————————
Serializable传递User值对象的代码:
首先User类要实现Serializable接口(public class User implements Serializable)
put:
Intent i = new Intent(......);
User user = new User();
user.setUserName("zhangsan");
user.setUserAge("11");
i.putExtra("user",user);
get:
Intent i = getIntent();
User user = (User) i.getSerializableExtra("user");
System.out.println(user.getUserName());
————————————————
Parceliable传递User值对象的代码:
首先User类要实现Parceliable接口,并且Override两个方法describeContents()、writeToParcel(),还需要在类中添加一个静态成员变量CREATOR,这个变量需要实现 Parcelable.Creator 接口。
简言之:通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射成你的对象。也可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面,再通过createFromParcel从流里读取对象,只不过这个过程需要你来实现,写的顺序和读的顺序必须一致。
public class User implements Parceliable{
......
@Override
public int describeContents(){ //这个不用管
return 0;
}
@Override
public void writeToParcel(Parcel dest , int flags){
dest.writeString(getUserName());
dest.writeString(getUserAdd());
dest.writeInt(getUserAge());
}
public static final Creator<User> CREATOR = new Creator<User>{
@Override
public User createFromParcel(Parcel source){
User user = new User();
user.setUserName(source.readString());
user.setUserAdd(source.readString());
user.setUserAge(source.readInt());
return user;
}
@Override
public User[] newArray(int size){
return new User[size];
}
}
}
下面是将Uesr对象进行传递的代码
put:
User user = new User();
user.setUserName("zhangsan");
user.setUserAdd("shagnhai");
user.setUserAge(11);
Intent i = new Intent(......);
i.putExtra("user",user);
get:
Intent i = getIntent();
User user = i.getParcelableExtra("user");
System.out.println(user.getUserName());
注:其中public static final一个都不能少,内部对象CREATOR的名称也不能改变,必须全部大写。需重写本接口中的两个方法:createFromParcel(Parcel in) 实现从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层,newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话即可(return new T[size]),供外部类反序列化本类数组使用。
————————————————
从上面的代码我们可以看到,Serializable和Parcelable的区别主要是对自定义数据进行处理。