Android重修课 -- Serializable&Parcelable

1. 从序列化开始说起

首先我们来看看什么是序列化。 序列化是指将数据结构对象转换成可取用格式(例如存成文件,存于缓冲,或经由网络中发送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程。反序列化就是序列化的逆向过程。

在我看来,实际意义上的序列化指的是将内存中的对象通过某种方式转变成为数据流的过程。至于将形成的数据流存于文件或者通过网络传输应该是另外一个的话题了。

2. 那么为什么需要序列化

很多数据对象我们在内存中可以使用,然后如果存在跨线程、跨进程、跨内存甚至跨主机的时候想要使用相同对象的话。我们就需要一个将数据发送过去的过程,这个过程我们可以将内存中的对象转化成数据流对象,通过保存到本地文件之类的方法传递到将要被使用的地方。而在java中,就为我们提供了从内存对象转换成数据流这样的方案,Serializable

3. 普通的序列化方式是什么呢

Serializable是java提供的标准的序列化和反序列化的接口。它是一个空接口,为对象提供标准的序列化和反序列化操作。优点是使用方便,只需要实现serializable接口即可。代价是在序列化和反序列化的时候,会使用到反射,并且会创建许多临时对象,导致更多的gc,导致性能不佳。

我们来看看它的使用方式

public class UserInfo implements Serializable {

    private static final long serialVersionUID = 1L;
    public String userId;
    public String name;
    public int age;

}
复制代码

就像上面代码所示,我们只需要实现Serializable即可,并指定一个serialVersionUID即可。实际上,serialVersionUID并不是必要的,我们也可以不指定,因为这个UID只是用于辅助序列化和反序列化过程,说白了,就是一个标识,表明我们在序列化和反序列化的操作针对的是同一种类型。

4. 为什么有了Serializable我们还需要使用Parcelable呢

在Android系统中,我们组件与组件之间,进程与进程之间也是需要通讯的,需要将内存中的对象传递。当然Serializable是可以实现这个功能的。然后Serializable是有它的缺点的,使用Serializable的序列化和反序列化的时候,会使用到反射,并且会创建许多临时对象,导致更多的gc,导致性能不佳。所以在Android中,内置了一个更加高效优雅的序列化和反序列方式,Parcelable

5. Parcelable是什么

是Android sdk提供的序列化接口。是通过安卓系统的Parcel机制来进行序列化和反序列化。

使用方式

public class UserInfo implements Parcelable {

    public String userId;
    public String name;
    public int age;

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.userId);
        dest.writeString(this.name);
        dest.writeInt(this.age);
    }

    public UserInfo() {
    }

    protected UserInfo(Parcel in) {
        this.userId = in.readString();
        this.name = in.readString();
        this.age = in.readInt();
    }

    public static final Parcelable.Creator<UserInfo> CREATOR = new Parcelable.Creator<UserInfo>() {
        @Override
        public UserInfo createFromParcel(Parcel source) {
            return new UserInfo(source);
        }

        @Override
        public UserInfo[] newArray(int size) {
            return new UserInfo[size];
        }
    };
}
复制代码

6. 为什么Parcelable会比Serializable更高效呢

因为Parcelable实现序列化的方法是通过Parcel来实现的,我们在实现Parcelable接口的时候,需要自己编写代码实现writeToParcel()createFromParcel()的过程,所以说Parcelable是通过自定义转换的方式来实现序列化和反序列过程。其中不会产生垃圾,效果就会比Serializable更好。如果我们把实现Serializable的方式改成自己实现writeObject()readObject(),那么两者效率不会相差太大。

7. 那在Android开发中是不是可以完全使用Parcelable替代Serializable呢

答案是不一定的,关键还是要看你对象的使用场景,如果你的内存对象只需要在Android组件中,或者Android进程之间传递使用的话,使用Parcelable效果是更好的。如果你的内存对象可能被存储到本地或者传输到网络中的话,使用Serializable是更加有保证性的。

猜你喜欢

转载自juejin.im/post/5c32041c51882525a3009be8