两种序列化方式的比较Serializable和Parcelable"/>
Android中两种序列化方式的比较Serializable和Parcelable
Android中两种序列化方式的比较Serializable和Parcelable - wcl_android@163
来源:互联网 更新时间:2017/3/13 14:16:28 责任编辑:李志喜 字体: 大 中 小Serializable和Parcelable接口可以完成对象的序列化过程,当我们需要通过Intent和Binder传输数据时就需要使用者两种序列化方式。还有,我们需要对象持久化到存储设备或者通过网络传输给其他客户端,这个使用也需要使用Serializale来完成对象的序列化。在Android应用开发中,这两种方式都很常见,但两者方式并不相同。
1.Serializable接口
Serializable接口是Java提供的一个序列化接口,它是一个空接口,为对象提供标准的序列化和反序列化操作。使用Serializable来实现的对象的序列化相当简单,只需要在类的生命中指定一个类似相面的标识即可自动实现默认的序列化过程。
private static final long serialVersionUID=871238749032;
完整的对象序列化代码示例如下:
//Model
public class User implements Serializable{private static final long serialVersionUID=871238749032;public int userId;public String userName;public String password;
}//序列化到本地
User user=new User(0,"wcl_android@163","123456");
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("user.obj"));
out.writeObject(user);
out.close;//反序列化
ObjectInputStream in=new ObjectInputStream(new FileInputStream("user.obj"));
User user=(User)in.readObject();
in.close();
这种方式是Java提供的一种序列化方式,过程非常简单,甚至有些开发人员都不需要声明serialVersionUID也可以完成这个过程,但serialVersionUID到底需不需要指定呢?
需要!
Java API既然提供了这个serialVersionUID,那么它必定是有用的。这个serialVersionUID是用来辅助序列化和反序列化过程的,原则上序列化后的数据中的serialVersionUID只有和当前类的serialVersionUID相同才能够正常地被反序列化。
serialVersionUID的详细工作过程是这样的:序列化的时候系统会把当前类的serialVersionUID写入序列化的二进制文件中,当反序列化的时候系统会检测文件中的serialVersionUID是否和当前类的serialVersionUID一致,如果一致就说明序列化的类的版本和当前类的版本是相同的,这个时候可以成功反序列化;否则说明当前类和反序列化的类相比发生了某些变化,比如成员变量的数量、类型发生了变化,这个时候是无法正常反序列化的。
一般来说,我们应该手动指定serialVersionUID的值,比如1L,也可以让IDE根据当前类的结构自动去生成它的hash值,这样序列化和反序列化时两者的serialVersionUID是相同的,因此可以正常进行反序列化操作。如果不手动指定serialVersionUID的值
反序列化时当前类有些改变,比如增加或者删除了某些成员变量,那么系统就会重新计算当前类的hash值并把它赋值给serialVersionUID,这个时候当前类的serialVersionUID就和反序列化数据中的serialVersionUID不一致,就会造成反序列化失败的结果。所以,手动指定serialVersionUID可以在很大程度上避免反序列化过程的失败。
比如当版本升级后,我们可能删除了某个成员变量也可能增加了一些新的成员变量,这个时候我们的反序列化过程依然能够成功,程序仍然能够最大限度地回复数据;相反,如果不指定serialVersionUID的话,程序会发生Crash。
当然,我们还需要考虑一种情况,如果类结构发生了非城规改变,比如修改了类名,修改了成员变量的类型,这个时候尽管serialVersionUID验证通过了,但是反序列化过程仍然会失败,因为类的结构有了毁灭性的改变,根本无法从老版本的数据中还原出一个新的类结构的对象。
对于使用序列化还有两点需要注意:
1.静态成员变量属于类不属于对象,所以不参与序列化过程
2.用transient关键字标记的成员变量不参与序列化过程
2.Parcelable接口
Parcelable接口是Android SDK提供的一种专门用于Android应用中对象的序列化和反序列化的方式,相比于Seriablizable具有更好的性能。实现Parcelable接口的对象就可以实现序列化并可以通过Intent和Binder传递。
下面是一个完成的实现了Parcelable接口的类
public class User implements Parcelable{public int userId;public String userName;public String password;public Book book;public User(int userId,String userName,String password,Book book){this.userId=userId;this.userName=userName;this.password=password;this.book=book;}public int describeContents(){//几乎所有情况都返回0,仅在当前对象中存在文件描述符时返回1return 0;}public void writeToParcel(Parcel out,int flags){out.writeInt(userId);out.writeString(userName);out.writeString(password);out.writeParcelable(book,0);}public static final Parcelable.Creator<User> CREATOR=new Parcelable.Creator<User>(){public User createFromParcel(Parcel in){return new User(in);}public User[] newArray(int size){return new User[size];}}private User(Parcel in){userId=in.readInt();userName=in.readString();password=in.readString(); book=in.readParcelable(Thread.currentThread().getContextClassLoader());}
}
看起来比Serializable方式复杂太多。我们使用表格把Parcelable方式的相关方法进行说明
方法功能标记位createFromParcel(Parcel in)从序列化后的对象中创建原始对象newArray(int size)创建指定长度的原始对象数组User(Parcel in)从序列化后的对象中创建原始对象writeToParcel(Parcel out,int flags)将当前对象写入序列化结构中PARCALABLE_WRITE_RETURN_VALUEdescribeContents返回当前对象的内容描述,几乎所有情况都返回0,仅在当前对象中存在文件描述符时返回1CONTENTS_FILE_DESCRIPTOR
温馨提示:如本文未解决您的问题或者其他方面的问题,请添加我们统一服务微信公众号:VC说(微信搜索公众号:vcshuo),请留言您需要处理的问题即可。
最新添加资讯
- 娱乐圈里“车震门”主角现状 钟嘉欣车震导致车祸
- 悉数娱乐圈和女友闺密偷腥的10大男星
- 狼狈不堪沦落到夜店卖唱的10大明星
- 令万千宅男垂涎的10大美艳女星 忍不住一亲芳泽
- 四川惊现百年的清朝老尸,赶尸匠赶尸入坟
- 实拍深圳夜场男公关个个龙精虎猛
- 海南师大女生宿舍换衣遭偷拍全集
- 明星遭遇揩油的瞬间
- 十大美女主播突遭意外的尴尬瞬间
- 娱乐圈因性感走红的情色女神
- 真人示范! 女用避孕套使用方法
- 实拍中国妓女村 一人一天接待13个客人
- 母狗竟产下人形狗崽
- 男子与价值8000美元充气娃娃谈恋爱
- 北京后海酒吧舞者妖娆多姿
- 模特不惧严寒 冰天雪地穿比基尼滑雪
- 墨西哥女孩被拐4年接客4万次
- 美女出位动作让人情迷意乱
- “越南奶茶妹”自评走红中国网络
- 韩国三姐妹一年内整容超百次 吃饭钱也省下
更多推荐
Android中两种序列化方式的比较Serializable和Parcelable
发布评论