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
- Parcelable only operates on memory and is not serialized into ongoing binary; Serializable is serialized into binary byte data by stream operation objects;
- Serializable uses a lot of reflection and temporary variables, which are lower in performance than Parcelable;
- 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:
- 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.
- 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.