Parcelable is a serialization class designed by the Google team for Android. Why Parcelable when Serializable is already available in Java? The Serializable serialization principle should be understood first by reading the Parcelable implementation class and source code.

1. The implementation class

Let’s look at an entity class that implements Parcelable.

public class Person implements Parcelable {

    private String name;
    private int sex;
    private int age;
    private String phone;


    protected Person(Parcel in) {
        name = in.readString();
        sex = in.readInt();
        age = in.readInt();
        phone = in.readString();
    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

        @Override
        public Person[] newArray(int size) {
            return newPerson[size]; }};@Override
    public int describeContents(a) {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeInt(sex); dest.writeInt(age); dest.writeString(phone); }}Copy the code

DescribeContents () (1), newArray(int size) (int size) Focus on the createFromParcel() and writeToParcel() methods. WriteToParcel () is the serialization method and createFromParcel() is the deserialization method. Both methods are called to serialize and deserialize data objects, whether they are passed when an Activity is started or used in AIDL.

2. Source code analysis

Start by analyzing the serialization writeToParcel() method, which serializes the data through the Parcel object passed in.

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(name);
    dest.writeInt(sex);
    dest.writeInt(age);
    dest.writeString(phone);
}
Copy the code

Let’s trace what’s written to String and see.

public final void writeString(@Nullable String val) {
    writeString16(val);
}
Copy the code

Go further.

public final void writeString16(@Nullable String val) {
    mReadWriteHelper.writeString16(this, val);
}
Copy the code

A helper class method is called, passing in both itself and serialized data.

public void writeString16(Parcel p, String s) {
    p.writeString16NoHelper(s);
}
Copy the code

Ultimately, it’s the call to the Parcel method.

public void writeString16NoHelper(@Nullable String val) {
    nativeWriteString16(mNativePtr, val);
}
Copy the code

NativeWriteString16 () is a local method.

@FastNative
private static native void nativeWriteString16(long nativePtr, String val);
Copy the code

Deserialize the createFromParcel() method.

public Person createFromParcel(Parcel in) {
    return new Person(in);
}
Copy the code

Data is also handled through Parcel objects. The Person argument constructor is called directly and a Parcel object is passed in.

protected Person(Parcel in) {
    name = in.readString();
    sex = in.readInt();
    age = in.readInt();
    phone = in.readString();
}
Copy the code

Let’s also look at how String data is read.

public final String readString(a) {
    return readString16();
}
Copy the code

Further.

public final @Nullable String readString16(a) {
    return mReadWriteHelper.readString16(this);
}
Copy the code

Again, the helper class method is called, passing in itself.

public String readString16(Parcel p) {
    return p.readString16NoHelper();
}
Copy the code

The method on the Parcel object is called again.

public @Nullable String readString16NoHelper(a) {
    return nativeReadString16(mNativePtr);
}
Copy the code

The local method is called again.

@FastNative
private static native String nativeReadString16(long nativePtr);
Copy the code

Deserialization can only be traced as far as this and all operations are done via the Parcel class, but the source code for serialization and deserialization is very simple and exposes very little to us. The core data processing is native, leaving us wondering where the data actually goes. In fact, it creates a local shared memory, points to the memory, and stores data there.

3.Parcelable VS Serializable

  1. Parcelable only operates on memory and is not serialized into ongoing binary; Serializable is serialized into binary byte data by stream operation objects;
  2. Serializable uses a lot of reflection and temporary variables, which are lower in performance than Parcelable;
  3. Serializable can be passed into a stream object for serialization and deserialization, while Parcelable implements serialization and deserialization internally.

4. To summarize

Based on the above analysis, the following conclusions can be drawn:

  1. Parcelable is only suitable for IPC communication on Android. It is recommended to use Parcelable to improve performance. Note, however, that because Parcelable is a memory operation, a large amount of object data may cause memory overflow.
  2. Serializable can be used for IPC, local storage, and network transfers, but with a lot of reflection and temporary variables, it is less performance than Parcelable.