IPC基础概念介绍第一篇(Serializable接口)

IPC主要包括Serializable接口,Parcelable接口以及Binder。

1.Serializable是java所提供的一个序列化接口,它是一个空接口,为对象提供标准的序列化和反序列化操作。使用Serializable来实现序列化相当简单,只需要在类中申明如下指定一个表示符即可实现默认序列化过程。

private static final long serialVersionUID=8711368828010083044L;

在android中也提供了新的序列化,那就是Parcelable接口,使用Parcelable来实现对象的序列化,其过程要稍微的复杂一些。上面提到,想让一个对象实现序列化,只需要实现Serializable接口并指明一个serialVersionUID即可,实际上,甚至这个serialVersionUID也不是必须的,我们不需要声明这个UID同样也可以实现序列化,但是这将会对反序列化过程产生影响,具体什么影响后面在介绍。User类就是一个实现Serializable接口的类,它是可以被序列化和反序列化的。

public class User implements Serializable{

    private static final long serialVersionUID=8711368828010083044L;

    private int userId;
    private String userName;
    private boolean isMale;
    ...
}

通过Serializable方式来实现对象的序列化,实现起来非常简单,几乎所有的工作都被系统自动完成了。如何进行对象的序列化和反序列化也非常简单,只需要采用ObjectOutputStream和ObjectInputStream即可轻松实现。

//序列化过程
    User user=new User(0,"amao",true);
    ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("cache.txt"));
    out.writeObject(user);
    out.close();

    //反序列化
    ObjectInputStream in=new ObjectInputStream(new FileInputStream("cache.txt"));
    User newUser=(User)in.readObject(user);
    in.close();

上诉代码演示了采用Serializable方式序列化对象典型过程,很简单,只需要把实现了Serializable接口的User对象写到文件中就可以快速恢复了,恢复后的对象newUser和user的内容完全一样,但两者并不是同一个对象。

刚开始提到,即使不指定UID也可以实现序列化,那到底要不要指定呢?如果指定的话,UID后面那一长串数字又是什么含义呢?我们要明白,系统既然提供了这个UID,那么它必须是有用的。这个UID实际上是来辅助序列化和反序列化过程的,原则上序列化后的数据中的UID只有和当前类的UID相同才能够正常的被序列化。UID的详细工作机制是这样的:序列化的时候系统会把当前类的UID写入序列化的文件中(也可能是其他中介),当反序列化的时候系统会去检测文件中的UID,看它是否和当前类的UID一致,如果一致就说明序列化的类的版本和当前类的版本是相同的,这个时候可以反序列化成功;否则就说明当前类和序列化的类相比发生了某些变化,比如成员变量的数量,类型可能发生改变,这个时候无法正常序列化,回报UID不同的错误。

一般来说,我们应该手动指定UID的值,这样在序列化和反序列化是两者的UID是相同,可以正常的进行反序列化。如果不手动指定UID,当你增加或删除某些成员变量的时候,那么系统会重新计算当前类的hash值并把它赋予给UID,这个时候当前的UID就和反序列化的UID就不同了,于是反序列化失败,程序crash掉了,但指定了就不会crash。当然,如果类的结构发生的改变,比如修改了类名,修改了成语变量的类型,这个时候尽管UID是一致的,反序列化还是会失败,因为类的结构有毁灭性的改变,根本无法从来版本的数据中还原出一个新的类结构对象。

根据上面的分析,我们可以知道手动给定UID和不给UID的区别。以下两点需要特别提一下,首先静态成员变量属于类不属于对象,所以不参加序列化过程;其次用transient关键字标记的成员变量不参与序列化过程。

另外,系统默认的序列化过程是可以改变的,通过实现如下两个方法即可重写系统默认的序列化和反序列化过程。

private void writeObject(ObjectOutputStream out)throws IOException{

    }

    private void readObject(ObjectInputStream in)throws IOException ,ClassNotFoundException{

    }
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值