Android系统之Serializable和Parcelable的区别

1. Serializable和Parcelable的定义

1.1 Serializable

package java.io;
public interface Serializable {
}

实现示例:

public class Person implements Serializable{
	private String name;
	private int age;
	public void setName(String name) {
        this.name = name;
    }
	public String getName() {
        return name;
    }
	public void setAge(int age) {
        this.age = age;
    }
	public int getAge() {
        return age;
    }
}

1.2 Parcelable

public interface Parcelable 
{
    //内容描述接口,基本不用管
    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 Person implements Parcelable{
	private String name;
	private int age;
	public void setName(String name) {
        this.name = name;
    }
	public String getName() {
        return name;
    }
	public void setAge(int age) {
        this.age = age;
    }
	public int getAge() {
        return age;
    }
	//这里的读的顺序必须与writeToParcel(Parcel dest, int flags)方法中写的顺序一致
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public Person() {
        super();
    }
    //这里的读的顺序必须与writeToParcel(Parcel dest, int flags)方法中写的顺序一致,否则数据会有差错
    public Person(Parcel source) {
        name = source.readString();
        age = source.readInt();
    }
    //这里默认返回0即可
    @Override
    public int describeContents() {
        return 0;
    }
    //把值写入Parcel中
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
    }
    public static final Creator<Person> CREATOR = new Creator<Person>() {
        //供外部类反序列化本类数组使用
        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
        //从Parcel中读取数据
        @Override
        public Person createFromParcel(Parcel source) {
            return new Person(source);
        }
    };
}

Serializable实现与Parcelabel实现的区别
a. Serializable的实现,只需要implements Serializable即可。这只是给对象打了一个标记,系统会自动将其序列化。
b. Parcelabel的实现,不仅需要implements Parcelabel,还需要在类中添加一个静态成员变量CREATOR,这个变量需要实现Parcelable.Creator接口。

2. implements Serializable和Parcelabel的意义

2.1 implements Serializable的意义

对象什么时候需要进行序列化?
a. 当你想把的内存中的对象写入到硬盘的时候
例如:内存不够用了,那计算机就要将内存里面的一部分对象暂时的保存到硬盘中,等到要用的时候再读入到内存中,硬盘的那部分存储空间就是所谓的虚拟内存。在比如过你要将某个特定的对象保存到文件中,我隔几天在把它拿出来用,那么这时候就要实现Serializable接口。
b. 当你想用套接字在网络上传送对象的时候
例如:在进行Java的Socket编程的时候,你有时候可能要传输某一类的对象,那么也就要实现Serializable接口。最常见的你传输一个字符串,它是JDK里面的类,也实现了Serializable接口,这样做为的是将数据变为二进制来传输,所以可以在网络上传输。
c. 当你想通过RMI传输对象的时候
例如:如果要通过远程的方法调用(RMI)去调用一个远程对象的方法,如在计算机A中调用另一台计算机B的对象的方法,那么你需要通过JNDI服务获取计算机B目标对象的引用,将对象从B传送到A,就需要实现序列化接口。

一个类只有实现了Serializable接口,它的对象才是可序列化的。因此如果要序列化某些类的对象,这些类就必须实现Serializable接口。而实际上,Serializable是一个空接口,没有什么具体内容,它的目的只是简单的标识一个类的对象可以被序列化。
例如:
public class Test implements Serializable{
private int id;
private String name;
……
}
如果没有用implements Serializable时,数据以此Test对象封装存进数据库,当要取出时,即使SQL在数据库中能正确返回数据,但sessionFactory.getCurrentSession().createNativeQuery(SQL,Test.class).list()返回的数据中字段内容都是空(数据条目数量正常不受影响),从而会导致诸如Method threw ‘javax.persistence.PersistenceException’ exception.等错误。
总结:implements Serializable的意义是实现序列化,保证数据完璧归赵的取或读。

2.2 implements Parcelabel的意义
implements Parcelabel的意义和implements Serializable相同,都是实现序列化,区别如下:
a. 在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。
b. Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
c. Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable。

总结:
实现Serializable和Parcelable都是为了实现序列化,二者的区别体现在两个地方:
a. 实现Serializable接口非常简单,声明一下就可以了;但是实现Parcelable需要重写writeToParcel方法、重写describeContents方法、实例化静态内部对象CREATOR实现接口Parcelable.Creator
b. 在使用内存的时候,Parcelable比Serializable性能高,因此推荐使用Parcelable。

好文:
https://www.cnblogs.com/renqingping/archive/2012/10/25/Parcelable.html
https://blog.csdn.net/am540/article/details/82498298

上一篇:IDEA自动生成序列化ID


下一篇:Shiro快速入门 —— 6.记住我