两种序列化的方法 Serializable Parcelable
原文:https://blog.csdn.net/hacker_crazy/article/details/80840868
一、Serializable
1.Serializable 是java的序列化技术,最简单的使用方式为在需要序列化的class增加implements Serializable,并增加一个唯一个序列化id: private static final long serialVersionUID = 1L; 默认方式最好直接设置为1L,因为java sdk会自动进行hash计算,并生成唯一的UID值。手动设置serialVersionUID的好处是当前class如果改变了成员变量,比如增加或者删除之后,这个UID是不改变的,那么反序列化就不会失败;自动设置则在改变了成员变量之后就会重新计算获得新的UID,从而导致失败。不过,大多数情况下两者都可以。如果该类变量不会存储到本地(数据库等)中,那不设置serialVersionUID也没关系,因为序列化之后的数据serialVersionUID在反序列时跟类的serialVersionUID是一致的。如果保存到本地了,万一哪个版本改了这个类,那么反序列化的时候serialVersionUID值不同,就会有问题。
2.Seralizable相对Parcelable而言,好处就是非常简单,只需对需要序列化的类class执行就可以,不需要手动去处理序列化和反序列化的过程,所以常常用于网络请求数据处理,Activity之间传递值的使用。
3.Seralizable无法序列化静态变量,使用transient修饰的对象也无法序列化。
4、Activity之间传递值使用时:
public class A implements Serializable { //序列化id private static final long serialVersionUID = 1L; private String str; //private B b; //这里如果使用到了自定义的另一个类对象,则该类也要实现Serializable接口。 public MyProduction(String str){ this.str = str; } //获值函数 public String getStr() { return str; } //赋值函数 public void setStr(String str) { this.str = str; } }
A a = new A(); a.setStr("Hello"); bundle.putSerializable("MySerializable", a); intent.putExtras(bundle); startActivity(intent);
5、序列化的步骤:
- 首先要创建某些OutputStream对象:OutputStream outputStream = new FileOutputStream("output.txt")
- 将其封装到ObjectOutputStream对象内:ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
- 此后只需调用writeObject()即可完成对象的序列化,并将其发送给OutputStream:objectOutputStream.writeObject(Object);
- 最后不要忘记关闭资源:objectOutputStream.close(), outputStream .close();
6、反序列化的步骤:
- 首先要创建某些OutputStream对象:InputStream inputStream= new FileInputStream("output.txt")
- 将其封装到ObjectInputStream对象内:ObjectInputStream objectInputStream= new ObjectInputStream(inputStream);
- 此后只需调用readObject()即可完成对象的反序列化:objectInputStream.readObject();
- 最后不要忘记关闭资源:objectInputStream.close(),inputStream.close();
二、Parcelable
1.Parcelable是android特有的序列化API,它的出现是为了解决Serializable在序列化的过程中消耗资源严重的问题,但是因为本身使用需要手动处理序列化和反序列化过程,会与具体的代码绑定,使用较为繁琐,一般只获取内存数据的时候使用。
2.而Parcelable依赖于Parcel,Parcel的意思是包装,实现原理是在内存中建立一块共享数据块,序列化和反序列化均是操作这一块的数据,如此来实现。
3、使用时需要实现4个方法:
public class ParcelableGroupBean implements Parcelable { private String mName; private List<String> mMemberNameList; private User mUser; /** * 需要我们手动创建的构造函数 * @param name * @param memberNameList * @param user */ public ParcelableGroupBean(String name, List<String> memberNameList, User user) { mName = name; mMemberNameList = memberNameList; mUser = user; } /** * 1.内容描述 * @return */ @Override public int describeContents() { //几乎都返回 0,除非当前对象中存在文件描述符时为 1 return 0; } /** * 2.序列化 * @param dest * @param flags 0 或者 1 */ @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(mName); dest.writeStringList(mMemberNameList); dest.writeParcelable(mUser, flags); } /** * 3.反序列化 */ public static final Creator<ParcelableGroupBean> CREATOR = new Creator<ParcelableGroupBean>() { /** * 反序列创建对象 * @param in * @return */ @Override public ParcelableGroupBean createFromParcel(Parcel in) { return new ParcelableGroupBean(in); } /** * 反序列创建对象数组 * @param size * @return */ @Override public ParcelableGroupBean[] newArray(int size) { return new ParcelableGroupBean[size]; } }; /** * 4.自动创建的的构造器,使用反序列化得到的 Parcel 构造对象 * @param in */ protected ParcelableGroupBean(Parcel in) { mName = in.readString(); mMemberNameList = in.createStringArrayList(); //反序列化时,如果熟悉也是 Parcelable 的类,需要使用它的类加载器作为参数,否则报错无法找到类 mUser = in.readParcelable(User.class.getClassLoader()); } }