Android --- Serializable 接口与 Parcelable 接口的使用方法和区别,怎么选择?

Serializable 是 Java所提供的一个序列化接口,这里提到了序列化,那什么叫序列化和反序列化呢?

序列化就是将 Java 对象转换成二进制文件数据的过程。这样说可能不是很明白,举个例子:如果把一个房子比作一个对象,要把这个做房子搬到另外一个地方的话,直接挪动是不现实的,但是可以将房子拆成一个个小零件运输,到了目的地在组装成房子,这样就容易多了,这其中 “拆解” 的过程就是序列化,“重新组装” 就是反序列化。

说到这里,怎么实现序列化呢?

只需要在类的声明中指定一个类似下面的标识即可自动实现默认的序列化过程。


private static final long serialVersionUID = 51906712373232662L;



全部代码:


import java.io.Serializable;



public class User implements Serializable {

    private static final long serialVersionUID = 51906712373232662L;

    public int userId;

    public String userName;

    public boolean isMale;



    public User(int userId, String userName, boolean isMale) {

        this.userId = userId;

        this.userName = userName;

        this.isMale = isMale;

    }

}



对象的序列化和反序列化只需要采用 ObjectOutputStream 和 ObjectInputStream 即可轻松实现,如下:


 // 序列化过程,就是写的过程

 User user = new User(0, "Jack", true);

 ObjectOutputStream out;



 {

     try {

         out = new ObjectOutputStream(new FileOutputStream("user.txt"));

         out.writeObject(user);

         out.close();

     } catch (IOException e) {

         e.printStackTrace();

     }

 }

 // 反序列化过程,就是读的过程

 ObjectInputStream in;

 User newUser;



 {

     try {

         in = new ObjectInputStream(new FileInputStream("user.txt"));

         newUser = (User) in.readObject();

         in.close();

     } catch (ClassNotFoundException e) {

         e.printStackTrace();

     } catch (IOException e) {

         e.printStackTrace();

     }

 }



现在有个问题,serialVersionUID 是用来辅助序列化和反序列化过程的,原则上序列化后的数据中 serialVersionUID 只有和当前类的 serialVersionUID 相同才能够正常地被反序列化。不用它行不行,答案:不行。

serialVersionUID 的详细工作机制是这样的:序列化的时候系统会把当前的 serialVersionUID 写入序列化的文件中(也可能是其他中介),当反序列化的时候系统回去检测文件中的 serialVersionUID ,看它是否和当前类的 serialVersionUID 一致,如果一致就说明序列化类的版本和当前的版本是相同的,这个时候可以成功反序列化;否则就说明当前类和序列化的类相比发生了变化,这个时候是无法反序列化的,会报错。

再简单的说就是:反序列化时如果当前类有所改变,比如增加或者删除了某些成员变量,那么系统就会重新计算当前类的 hash 值并把它赋值给 serialVersionUID ,这个时候当前类的 serialVersionUID 就和序列化的数据中心的 serialVersionUID 不一致,于是反序列化失败,程序 crash。所以,我们可以明显感觉到 serialVersionUID 的作用。

Serializable 就介绍到这里了,再加一点比较重要的知识点:静态成员变量属于类不属于对象。所以不会参与序列化的过程,其次使用 transient 关键字编辑的成员变量不参与序列化过程。

三、Parcelable 接口

==============================================================================

我们在 Android Studio 中写了一个类 User 实现 Parcelable 接口


public class User implements Parcelable {

    public int userId;

    public String userName;

    public boolean isMale;



    @Override

    public int describeContents() {

        return 0;

    }



    @Override

    public void writeToParcel(Parcel parcel, int i) {



    }

}



这个时候就会爆红,我们把鼠标放到 User 上面然后按住 "Alt + Enter"键会出现下图的情况,点击第一个 Add Parcelable Implementation

在这里插入图片描述点击之后编辑器自动给我们写了序列化和反序列化过程,非常省事

在这里插入图片描述

我们看看全部代码:


import android.os.Parcel;

import android.os.Parcelable;



public class User implements Parcelable {

    public int userId;

    public String userName;

    public boolean isMale;



    protected User(Parcel in) {

        userId = in.readInt();

        userName = in.readString();

        isMale = in.readByte() != 0;

    }



    // 反序列化

    public static final Creator<User> CREATOR = new Creator<User>() {

        @Override

        public User createFromParcel(Parcel in) {

            return new User(in);

        }



        @Override

        public User[] newArray(int size) {

            return new User[size];

        }

    };



	// 内容描述

    @Override

    public int describeContents() {

        return 0;

    }



    // 序列化

    @Override

    public void writeToParcel(Parcel parcel, int i) {

        parcel.writeInt(userId);

        parcel.writeString(userName);

        parcel.writeByte((byte) (isMale ? 1 : 0));

    }

}



Parcelable 的方法说明

| 方法 | 功能 | 标记位 |

| — | — | — |

| createFromParcel(Parcel in) | 从序列化后的对象中创建原始对象 | |

| newArray(int size) | 创建指定长度的原始对象数组 | |

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值