您的位置:首页 > 移动开发 > Android开发

android里序列化和反序列化的综合分析

2017-07-09 15:20 253 查看
    1.什么叫做序列化与反序列化呢?

    java的序列化就是指把java对象转换成字节序列的过程。而java反序列化就是指把字节序列恢复为java对象的过程。

   2.为什么需要序列化和反序列化

   我们知道,当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本、图片、音频、视频等, 而这些数据都会以二进制序列的形式在网络上传送。那么当两个Java进程进行通信时,能否实现进程间的对象传送呢?答案是可以的。如何做到呢?这就需要Java序列化与反序列化了。换句话说,一方面,发送方需要把这个Java对象转换为字节序列,然后在网络上传送;另一方面,接收方需要从字节序列中恢复出Java对象。

   3.序列化和反序列化的好处

   好处一是实现了数据的持久化,为什么需要实现数据的持久化呢?是因为java中创建的对象都是存在于JVM的堆中的,而JVM处于运行状态的时候,这些对象可以复用,但是JVM一旦停止,这些对象的状态也就丢失了,因此需要实现数据的持久化。通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里),

    二是,利用序列化实现远程通信,即在网络上传送对象的字节序列。

    4.如何实现序列化

    Android里实现序列化有两种方式,一种是实现了Parcelable接口的类,还有一种是实现Serializable接口的类,该类可以手动声明      一个serialVersionUID,也可以让IDE自动帮我们生成(Eclipse会自动生成,AS需要而外设置一下)

     5.serialVersionUID的作用是什么

     Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本是否是一致的。在进行反序列化时,JVM会把传来的字节序列中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。 

     6.android中哪些是可以序列化的,哪些是不可以的?

     实现了Parcelable和Serializable的接口的类的对象是可以序列化的,除此之外,Android里的intent,Bundle,Bitmap是实现了Parcelable的类,因此是可以序列化的.List和Map也可以序列化,前提是他们里面的每个元素都是可以序列化的。

      一定要注意的是,基本类型是不能序列化的,可是如果他们的包装类(比如有个User类,里面有若干个由基本数据类型组成的成员变量,再比如Intent中也是可以放入基本数据类型)有实现Parcelable和Serializable的接口,那么该类就是可以序列化的。

此外要注意,类中的静态变量是不可以序列化的,因为静态变量属于类,不属于对象,而序列化和非序列化涉及的是对象。

      7.Parcelable的具体使用示范

      Parcelable接口主要有三个方法:

       public interface Parcelable
{
//内容描述接口,基本不用管,一般都是返回0,有文件描述符时返回1
public int describeContents();
//写入接口函数,数据打包
public void writeToParcel(Parcel dest, int flags);
//读取接口,目的是要从Parcel中构造一个实现了Parcelable的类的实例处理。因为实现类在这里还是不可知的,所以需要用到模板的方式,继承类名通过模板参数传入
//为了能够实现模板参数的传入,这里定义Creator嵌入接口,内含两个接口函数分别返回单个和多个继承类实例
public interface Creator<T>
{
public T createFromParcel(Parcel source);
public T[] newArray(int size);
}
}       下面是一个简单的示例:
           public class MyParcelable implements Parcelable
{
private int mData;

public int describeContents()
{
return 0;
}

public void writeToParcel(Parcel out, int flags)
{
out.writeInt(mData);
}

public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>()
{
public MyParcelable createFromParcel(Parcel in)
{
return new MyParcelable(in);
}

public MyParcelable[] newArray(int size)
{
return new MyParcelable[size];
}
};

private MyParcelable(Parcel in)
{
mData = in.readInt();
}
}        8.最重要的一点,Parcelable和Serializable的比较和区别

        1.Serializable的性能比Parcelable差,这是因为Serializable将对象转化为字节序列存储在外部设备(磁盘之中),需要时重新生成对象(依靠反射),这个过程需要大量的I/O操作,此外,会生成大量的临时变量,从而引起频繁的GC.因此,在内存中传输时更推荐Parcelable(比如在进程间传输对象,这也是为什么Intent会选择实现Parcelable接口的原因)

         2.话又说回来,Parcelable为了效率,完全没有考虑版本之间的兼容性和一致性(对比之前的Serializable的serialVersionUID),此外Parcelable整个过程就是在内存中进行的,序列化和反序列化过程中读取的就会原对象,不会创建新对象,因此也没法实现数据的持久化,例如没法实现将数据保存在磁盘上等等,所以要实现数据的持久化还是要使用Serializable(比如外部设备保存对象状态或者网络传输对象)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息