Android序列化

Android的两种序列化Serializable和Parcelable

1.Serializable接口

Serializable接口是Java提供的一个序列化接口,它是一个空接口,为对象提供标准的序列化和反序列化操作。使用Serializable来实现的对象的序列化相当简单,只需要在类的生命中指定一个类似相面的标识即可自动实现默认的序列化过程。

完整的对象序列化代码示例如下:

//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.com","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();


很多人都不知道serialVersionUID是否需要。

答案是肯定的,需要。为什么呢?

有些人就会说了,我没有写这个,也没有报错啊,当然一般不写也是没有问题的。

在什么时候需要用到它呢,就是当你序列化一个对象之后,然后增加或者减少了这个该类的成员变量,然后再去进行之前那个对象的反序列化的时候,如果没有指定serialVersionUID,就会反序列化失败,然后抛出异常;如果指定了serialVersionUID,就不会有问题,系统会去找到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,仅在当前对象中存在文件描述符时返回1
        return 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());
    }
}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

比Serializable方式复杂太多。我们使用表格把Parcelable方式的相关方法进行说明

方法 功能 标记位
createFromParcel(Parcel in) 从序列化后的对象中创建原始对象  
newArray(int size) 创建指定长度的原始对象数组  
User(Parcel in) 从序列化后的对象中创建原始对象  
writeToParcel(Parcel out,int flags) 将当前对象写入序列化结构中 PARCALABLE_WRITE_RETURN_VALUE
describeContents 返回当前对象的内容描述,几乎所有情况都返回0,仅在当前对象中存在文件描述符时返回1 CONTENTS_FILE_DESCRIPTOR

既然Parcelable和Serializable都可以实现序列化并且可以用于Intent间的数据传递,那么两者有什么区别呢?

区别 Serializable Parcelable
所属API JAVA API Android SDK API
原理 序列化和反序列化过程需要大量的I/O操作 序列化和反序列化过程不需要大量的I/O操作
开销 开销大 开销小
效率 很高
使用场景 序列化到本地或者通过网络传输 内存序列化

序列化的目的

  (1).永久的保存对象数据(将对象数据保存在文件当中,或者是磁盘中

  (2).通过序列化操作将对象数据在网络上进行传输(由于网络传输是以字节流的方式对数据进行传输的.因此序列化的目的是将对象数据转换成字节流的形式)

  (3).将对象数据在进程之间进行传递(Activity之间传递对象数据时,需要在当前的Activity中对对象数据进行序列化操作.在另一个Activity中需要进行反序列化操作讲数据取出)

  (4).Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长(即每个对象都在JVM中)但在现实应用中,就可能要停止JVM运行,但有要保存某些指定的对象,并在将来重新读取被保存的对象。这是Java对象序列化就能够实现该功能。(可选择入数据库、或文件的形式保存)

  (5).序列化对象的时候只是针对变量进行序列化,不针对方法进行序列化.

  (6).在Intent之间,基本的数据类型直接进行相关传递即可,但是一旦数据类型比较复杂的时候,就需要进行序列化操作了.

大家可以根据实际开发情况,选择Parcelable和Serializable进行序列化。

比如需要对象持久化,保存到sd卡,就需要用Serializable,一些其他情况,需要时间越短的可以选择Parcelable。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值