Serializable and Parcelable serialization

foreword

There are two commonly used serialization methods in Android: Serializable and Parcelable. Among them, Serializable is a common object serialization method in java, and it will be more inclined to implement the Parcelable interface in the actual memory operation of Android.

1. Serialization and deserialization

Serialization

Since the objects in memory are temporary and cannot be stored for a long time, in order to maintain the state of the object, it is necessary to write the object to disk or other media. This process is called serialization.

deserialization

is the reverse operation of serialization.

In a nutshell, serialization refers to the process of storing the state of an object instance to a storage medium (disk or other medium). In this process, the public and private fields of the object and the name of the class (including the assembly where the class is located) are converted into a byte stream, and then the byte stream is written into the data stream. When the object is subsequently deserialized, an exact copy of the original object will be created.

2. Serialization Application Scenarios

There are mainly the following situations (but not limited to the following situations)
1) Objects in memory are written to the hard disk;
2) Data transmission (such as Intent, Binder)

3. Serialization process

For an object to implement serialization operations, the class must implement the Serializable interface or the Parcelable interface. The Serializable interface is an abstract serialization class in Java, and the Parcelable interface is a unique serialization interface in Android. In some cases , the serialization implemented by the Parcelable interface is more efficient.

1. Serializable

Just implement the Serializable interface in the class declaration. It is recommended to actively declare the serialization ID. The identification ID can be automatically generated, and the active declaration is only for higher guarantee of normal deserialization.

The serialization identification ID uses the identification serialization class. Only when the serialization identification is consistent can it be deserialized normally. The serialized and deserialized IDs must be the same for the serialization operation to succeed.

  1. If you do not manually specify the value of serialVersionUID, the compiler will calculate the hash value as the UID based on the current class structure
  2. If the value of serialVersionUID is not manually specified, the deserialization is a change in the current class, and the calculated hash value will be inconsistent, which will cause the current deserialization to report an error crash.
  3. If the class structure undergoes unconventional changes, such as modifying the class name, modifying the member variable type, even if the UID verification passes at this time, the deserialization will report an error, and a new type of structural object cannot be restored.

sample code

// 构造对象
        User user = new User();
        user.setId(1000);
        user.setName("张三");

        // 把对象序列化到文件
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/serializable/user.txt"));
        oos.writeObject(user);
        oos.close();

        // 反序列化到内存
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/serializable/user.txt"));
        User userBack = (User) ois.readObject();
        System.out.println("read serializable user:id=" + userBack.getId() + ", name=" + userBack.getName());
        ois.close();

Only ObjectOutStream and ObjectInputStream can be used to implement serialization and deserialization of objects.

The deserialized object is newly created, not the same as the original object.

2. Parcelable

Parcelable is an Android-specific serialization, which is slightly better than Serializable in terms of memory, and has a smaller overhead.

public class User implements Parcelable {

    public int id;
    public String name;
    public User friend;

    /**
     * 当前对象的内容描述,一般返回0即可
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * 将当前对象写入序列化结构中
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(this.id);
        dest.writeString(this.name);
        dest.writeParcelable(this.friend, 0);
    }

    public NewClient() {}

    /**
     * 从序列化后的对象中创建原始对象
     */
    protected NewClient(Parcel in) {
        this.id = in.readInt();
        this.name = in.readString();
       //friend是另一个序列化对象,此方法序列需要传递当前线程的上下文类加载器,否则会报无法找到类的错误
       this.friend=in.readParcelable(Thread.currentThread().getContextClassLoader());
    }

    /**
     * public static final一个都不能少,内部对象CREATOR的名称也不能改变,必须全部大写。
     * 重写接口中的两个方法:
     * createFromParcel(Parcel in) 实现从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层,
     * newArray(int size) 创建一个类型为T,长度为size的数组,供外部类反序列化本类数组使用。
     */
    public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
        /**
         * 从序列化后的对象中创建原始对象
         */
        @Override
        public User createFromParcel(Parcel source) {
            return new User(source);
        }

        /**
         * 创建指定长度的原始对象数组
         */
        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };
}

In fact, Parcelable objects need to be used when passing data of complex types (such as custom reference type data) through Intents. The following are some operation methods of Intents on Parcelable objects in daily applications. Reference types must implement the Parcelable interface to be passed through Intents, and basic The data type and the String type can be passed directly through the Intent and the Intent itself also implements the Parcelable interface, so it can be easily transferred between components.

Four, the difference between the two

1. Realize the difference

Serializable only needs to implement the Serializable interface. Parcelable needs to implement Parcelable, and a static member variable CREATOR needs to be added. This variable needs to implement the Creator interface and implement abstract methods for reading and writing.

2. The original design intention of the two

Serializable is mainly for serializing objects to local files, databases, network streams, etc.

Parcelable is mainly because data transfer in Android is mainly in the memory environment, so the emergence of Parcelable is to meet the low-overhead and efficient transfer of data in memory.

3. Application scenarios

Parcelable reads and writes directly in the memory. We know that the read and write speed of the memory is definitely faster than that of the hard disk, so the performance of the Parcelable serialization method is much better than that of the Serializable method. Therefore, Android applications are recommended to use Parcelable when transferring data between memories, such as transferring data between activities and AIDL data transfer.

Serializable uses IO to read and write to store on the hard disk. The serialization process uses reflection technology, and temporary objects are generated during the process, which has the advantage of less code. It is recommended to choose Serializable when serializing objects into storage settings or transferring objects through the network after serialization.

Guess you like

Origin blog.csdn.net/cat_is_so_cute/article/details/123475270