美文网首页Android
Android中Serializable和Parcelable接

Android中Serializable和Parcelable接

作者: MoonJoy | 来源:发表于2019-01-28 16:45 被阅读14次

    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<T> 
        {
               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<T> 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<Person> CREATOR = new Parcelable.Creator<Person>() 
         {
             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接

        本文链接:https://www.haomeiwen.com/subject/rxzojqtx.html