Android中Serializable和Parcelable接口

Android中实现序列化有两个选择:一个是实现Serializable接口,Java提供的一个序列化接口;另一个是实现Parcelable接口,Android特有的序列化接口,效率比实现Serializable接口高效,可用于Intent数据传递,也可以用于进程间通信(IPC)。

序列化和反序列化

  • 序列化:用来处理对象流的机制,所谓对象流就是将对象的内容进行流化。方便对流化后的对象进行读写操作,也可在网络间传输。简单来说是一种将对象以一连串的字节描述的过程。

  • 反序列化:将流化后的对象重新构成对象的过程。

序列化应用场景

  • 永久性保存对象,保存对象的字节序列到本地文件中
  • 通过序列化对象在网络中传输
  • 通过序列化在进程间传递对象

Serializable序列化ID:

序列化ID serialVersionUID的值可以是固定的1L,也可以是随机生成一个不重复的long类型数据,甚至可以不声明也可以实现序列化。但是会对反序列化过程产生影响,因为不同的序列化ID之间不能进行序列化和反序列化。

Serializable实现序列化步骤

  • 创建某些OutputStream对象:OutputStream outputStream = new FileOutputStream("output.txt");

  • 将其封装到ObjectOutputStream对象内:ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);

  • 调用writeObject()即可完成对象的序列化,并将其发送给OutputStream:objectOutputStream.writeObject(Object);

  • 关闭资源:objectOutputStream.close()和outputStream.close();

Serializable实现反序列化步骤

  • 创建某些InputStream对象:InputStream inputStream = new FileInputStream("output.txt");

  • 将其封装到ObjectInputStream对象内:ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);

  • 调用readObject()即可完成对象的反序列化:object = objectInputStream.readObject();

  • 关闭资源:objectInputStream.close()和inputStream.close();

注意:

  • 静态变量属于类不属于对象,所以不会参与序列化过程。
  • 用transient关键字标记的成员变量不参与序列化过程。(通过用这个关键字可以控制想要序列化的成员变量

Serializable代码实例:

public class Person implements Serializable {
    private static final long serialVersionUID = 1L;

    private String name;
    private int age;

    public Person(String name, int age) {
        this.name= name;
        this.age= age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name= name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

// Serializable:把对象序列化
public static void writeSerializableObject() {
    try {
        Person person = new Person("Mary", 18);
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("output.txt"));
        objectOutputStream.writeObject(person);
        objectOutputStream.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

// Serializable:反序列化对象
public static void readSerializableObject() {
    try {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("output.txt"));
        Person person = (Person) objectInputStream.readObject();
        objectInputStream.close();
        System.out.println("name = " + person.getName() + ", age = " + person.getAge());
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Parcelable接口定义

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

Parcelable实现序列化步骤

  • 实现Parcelable接口

  • 重写writeToParcel方法,将你的对象序列化为一个Parcel对象,即:将类的数据写入外部提供的Parcel中,打包需要传递的数据到Parcel容器保存,以便从 Parcel容器获取数据

  • 重写describeContents方法,内容接口描述,默认返回0就可以

  • 实例化静态内部对象CREATOR实现接口Parcelable.Creator。需重写本接口中的两个方法:createFromParcel(Parcel in) 实现从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层,newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话即可(return new T[size]),供外部类反序列化本类数组使用。

public static final Parcelable.Creator CREATOR

Parcelable代码实例:

public class Person implements Parcelable 
{
     private String name;
     private String sex;
     private int age;

     public int describeContents() 
     {
         return 0;
     }

     public void writeToParcel(Parcel out, int flags) 
     {
         out.writeString(name);
         out.writeString(sex);
         out.writeInt(age);
     }

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

         public Person[] newArray(int size) 
         {
             return new Person[size];
         }
     };
     
     private Person(Parcel in) 
     {
        name = in.readString();
        sex = in.readString();
         age = in.readInt();
     }
 }

Serializable和Parcelable对比

  • Serializable实现较简单,只需要implements Serializable即可,系统会自动将其序列化;而Parcelable的实现,不仅需要implements Parcelable,还需要在类中添加一个静态成员变量CREATOR,这个变量需要实现 Parcelable.Creator接口。

  • 使用内存时,Parcelable比Serializable性能高,推荐使用Parcelable。

  • Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable 。

你可能感兴趣的:(Android中Serializable和Parcelable接口)