1、Parcelable和Serializable有什么用,它们有什么差别?
Parcelable和Serializable可以完成对象的序列化,当我们需要用intent和Binder传输数据时,就需要用到Parceable和Serializable,或者我们需要吧对象持久化到设备上的时候,或者通过网络传输到其他客户端,这个时候需要Serializable来完成对象的持久化
Parcelable比Serialiable性能好,效率较快,在内存方面开销比较好,所以在内存中传输数据时推荐Parceable,而Serialiable可将数据持久化保存,所以在保存或者网络传输推荐Serialiable
2、自定义一个类让其实现Parcelable,大致流程是什么?
public class User implements Parcelable{
public String id;
public String name;
//从序列化对象中创建原始对象
protected User(Parcel in) {
id = in.readString();
name = in.readString();
}
public static final Creator<User> CREATOR = new Creator<User>() {
@Override
public User createFromParcel(Parcel in) {
//从序列化对象中创建原始对象
return new User(in);
}
@Override
public User[] newArray(int size) {
//创建指定长度的原始对象数组
return new User[size];
}
};
@Override
public int describeContents() {
//返回当前对象的内容的描述,如果含有文件描述返回1,否则返回0,一般都返回0
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
//将当前对象写入序列化结构中,其中flag有俩种值,0或1,为1时标识当前对象需要作为返回值返回,不能
//立即释放资源,一般为0
dest.writeString(id);
dest.writeString(name);
}
}
如何使用Serializable
直接实现该接口,添加一个serialVersionUID变量就完成了
public class Name implements Serializable {
private static final long serialVersionUID = 1L;
public String name;
}
序列化过程
//序列化过程
try {
Name name = new Name("测试");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("text.txt"));
objectOutputStream.writeObject(name);
objectOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
反序列化过程
//反序列化过程
try {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("text.txt"));
Name name = (Name) objectInputStream.readObject();
objectInputStream.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
不指定serialVersionUID也可以序列化,那么有没有必要指定serialVersionUID呢?
是需要的,因为序列化后只有和当前类的serialVersionUID一样,才可以反序列化,如果serialVersionUID不一样说明类结构发生了变化,就不可以反序列化,serialVersionUID可以手动指定,也可以hash动态生成
- 注意 静态变量属于类不属于对象,不会参与序列化
- transient 指定的变量不参与序列化