Android的序列化(Serializable和Parcelable)

【齐天的博客】转载请注明出处(万分感谢!):
https://blog.csdn.net/qijinglai/article/details/80813423

前言

Android中要实现对象持久化或者对象传输就一定会用到对象序列化的操作,Android中实现序列化的方式有两种,一种是实现Java中的Serializable接口,另一种是实现Android中的Parcelable接口。当然,既然Android专门提供了序列化接口,那么一定是Parcelable的效率会更高一点。下面我们分析一下这两种方式。

Serializable

它是Java提供的一个空接口,提供对象标准的序列化和反序列化操作,使用极简单。

使用

只需实现Serializable接口即可,可选择声明或不声明serialVersionUID,区别后面会说。

如何实现序列化和反序列化
//序列化
UserBean user = new UserBean();
ObjectOutputStream out = new ObjectOutputStream(
                    new FileOutputStream("cache.txt"));
out.writeObject(user);
out.close();

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

serialVersionUID

原则上序列化后的数据要和当前类有相同的serialVersionUID,才能正常被反序列化。

工作机制
  1. 序列化时会把serialVersionUID也一起写入
  2. 反序列化时检测serialVersionUID是否一致
    ·若一致,则反序列化成功
    ·不一致,说明类发生了某种变化(如:变量少了一两个,变量多了一两个等等)
例子

当版本升级后,我们可能删除了某几个成员变量,这时候如果是制定了serialVersionUID我们就依然可以反序列化成功,使程序最大限度的恢复数据。
但是如果有毁灭性的改变,比如修改了类名,这样就完全不可能被反序列化了。

Parcelable

只要实现这个接口的类的对象,就可以实现序列化,并可以通过Intent和Binder传递。

public class User implements Parcelable{

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

    private Book book;

    public User(int userId, String userName, boolean isMale) {
        this.userId = userId;
        this.userName = userName;
        this.isMale = isMale;
    }


    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeInt(userId);
        parcel.writeString(userName);
        parcel.writeInt(isMale?1:0);
        parcel.writeParcelable(book,0);
    }


    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];
        }
    };

    protected User(Parcel in) {
        userId=in.readInt();
        userName=in.readString();
        isMale=in.readInt()==1;
        book=in.readParcelable(Thread.currentThread().getContextClassLoader());

    }


}

模式都一样,这里只单独说一下Parcel,Parcel内部包装了可序列化的程序,可以再Binder中自由传输,在以后的IPC通信中将会用到。

总结

  • Serializable是Java中的接口,使用简单,但内部需要大量的IO操作,开销很大。
  • Parcelable是Android中的接口,使用麻烦,但效率很高

所以Android中首选Parcelable。Parcelable主要应用于在内存序列化上,但在存储设备及网络传输序列化时会显得太复杂,因此这两种情况使用Serilaizable会更好一些。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Qi T

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值