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<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 。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容