Android中使用Parcelable实现对象的序列化

在Android开发中,Parcelable是一个接口,只要实现这个接口,一个类的对象就可以实现序列化并可通过Intent和Binder传递。序列化的目的是传递数据用。

  • 下面给出一个实体类的序列化实例,大家可以参考这样来写,因为写法都是一样的:

public class User implements Parcelable{

    // 当前实体类的三个属性
    public int userId;
    public String userName;
    public boolean isMale;
    // 另外的实体类对象
    public Book book;

    // 添加一个有参的构造方法
    public User(int userId, String userName, boolean isMale) {
        super();
        this.userId = userId;
        this.userName = userName;
        this.isMale = isMale;
    }

    /**
     * 内容描述功能的实现
     */
    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    /**
     * 序列化功能实现
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        // TODO Auto-generated method stub
        dest.writeInt(userId);
        dest.writeString(userName);
        dest.writeInt(isMale ? 1:0);
        dest.writeParcelable(book, 0);
    }

    /**
     * 反序列化功能的实现
     */
    public static final Parcelable.Creator<User> CREATOR = new Creator<User>() {

        // 创建指定长度的原始对象数组
        @Override
        public User[] newArray(int size) {
            // TODO Auto-generated method stub
            return new User[size];
        }

        // 从序列化后的对象中创建原始对象
        @Override
        public User createFromParcel(Parcel source) {
            // TODO Auto-generated method stub
            return new User(source);
        }
    };

    private User(Parcel source){
        userId = source.readInt();
        userName = source.readString();
        isMale = source.readInt() == 1;
        // 由于book是一个可序列化的对象,所以它的反序列化过程需要传递当前线程的上下文加载器,否则会报无法找到类的错误。
        book = source.readParcelable(Thread.currentThread().getContextClassLoader());
    }

}
  • 从上述代码可以看出,在序列化过程中需要实现的功能有:序列化、反序列化和内容描述。

序列化功能由writeToParcel方法来完成,最终是通过Parcel中的一系列write方法来完成的;
反序列化功能由CREATOR来完成,其内部标明了如何创建序列化对象和数组,并通过Parcel的一系列read方法来完成反序列化的过程;
内容描述功能由describeContents方法来完成,几乎所有情况下这个方法都应该返回0,仅当当前对象中存在文件描述符时,此方法返回1。

  • 详细的方法说明请看下表:
方法功能标记位
createFromParcel(Parcel source)从序列化后的对象中创建原始对象
newArray(int size)创建指定长度的原始对象数组
User(Parcel source)从序列化后的对象中创建原始对象
writeToParcel(Parcel dest,int flags)将当前对象写入序列化结构中,其中flags标识有两种值:0或者1(参见右侧标记位)。为1时标识当前对象需要作为返回值返回,不能立即释放资源,几乎所有情况都为0PARCELABLE_WRITE_RETURN_VALUE
describeContents返回当前对象的内容描述。如果含有文件描述符,返回1,(参见右侧标记位),否则返回0,几乎所有情况都返回0CONTENTS_FILE_DESCRIPTOR

  • Android系统也有许多实现了Parcelable接口的类,它们都是可以直接序列化的,比如Intent、Bundle、Bitmap等,同时List和Map也可以序列化,前提是它们里面的每一个元素都是可序列化的。

当然还有Serializable也可以实现序列化,由于实现Serializable接口序列化的方法较为简单,这里就不多说了。就说一下Parcelable和Serializable实现序列化的时候,二者该如何选择。
Serializable是Java中的序列化接口,其使用起来简单,但是开销很大,序列化和反序列化过程需要消耗大量的I/O操作。而Parcelable是 Android中的序列化方式,因此更适合用在Android平台上,它的缺点就是使用起来稍微麻烦点,但是效率很高,这是Android推荐的序列化方式,因此我们要首选Parcelable。 Parcelable主要用在内存序列化上,通过Parcelable将对象序列化到存储设备中或者将对象序列化后通过网络传输也都是可以的,但是这个过程会稍显复杂,因此在这两种情况下建议大家使用Serializable。以上就是两者的区别。


每天进步一点点!加油!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值