简述:
Parcelable接口:Parcelable定义了将数据写入Parcel,和从Parcel中读出的接口。一个实体(用类来表示),如果需要封装到消息中去,就必须实现这一接口,实现了这一接口,该实体就成为“可打包的”了。
通过Parcelable接口进行序列化的优势:首先,IPC过程中使用;其次,Activity之间通过Intent通信时也更加方便;最后,永久性保存对象,保存对象的字节序列到本地文件中。
Parcelable接口源码:
下面是API23的源码:
public interface Parcelable {
/**
* Flag for use with {@link #writeToParcel}: the object being written
* is a return value, that is the result of a function such as
* "<code>Parcelable someFunction()</code>",
* "<code>void someFunction(out Parcelable)</code>", or
* "<code>void someFunction(inout Parcelable)</code>". Some implementations
* may want to release resources at this point.
*/
public static final int PARCELABLE_WRITE_RETURN_VALUE = 0x0001;
/**
* Bit masks for use with {@link #describeContents}: each bit represents a
* kind of object considered to have potential special significance when
* marshalled.
*/
public static final int CONTENTS_FILE_DESCRIPTOR = 0x0001;
/**
* Describe the kinds of special objects contained in this Parcelable's
* marshalled representation.
*
* @return a bitmask indicating the set of special object types marshalled
* by the Parcelable.
*/
public int describeContents();
/**
* Flatten this object in to a Parcel.
*
* @param dest The Parcel in which the object should be written.
* @param flags Additional flags about how the object should be written.
* May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
*/
public void writeToParcel(Parcel dest, int flags);
/**
* Interface that must be implemented and provided as a public CREATOR
* field that generates instances of your Parcelable class from a Parcel.
*/
public interface Creator<T> {
/**
* Create a new instance of the Parcelable class, instantiating it
* from the given Parcel whose data had previously been written by
* {@link Parcelable#writeToParcel Parcelable.writeToParcel()}.
*
* @param source The Parcel to read the object's data from.
* @return Returns a new instance of the Parcelable class.
*/
public T createFromParcel(Parcel source);
/**
* Create a new array of the Parcelable class.
*
* @param size Size of the array.
* @return Returns an array of the Parcelable class, with every entry
* initialized to null.
*/
public T[] newArray(int size);
}
/**
* Specialization of {@link Creator} that allows you to receive the
* ClassLoader the object is being created in.
*/
public interface ClassLoaderCreator<T> extends Creator<T> {
/**
* Create a new instance of the Parcelable class, instantiating it
* from the given Parcel whose data had previously been written by
* {@link Parcelable#writeToParcel Parcelable.writeToParcel()} and
* using the given ClassLoader.
*
* @param source The Parcel to read the object's data from.
* @param loader The ClassLoader that this object is being created in.
* @return Returns a new instance of the Parcelable class.
*/
public T createFromParcel(Parcel source, ClassLoader loader);
}
}
Parcelable接口原理:
假设对象A实现了Parcelable接口,那么首先会通过writeToParcel()方法将对象A写入到Parcel对象中去。数据传递完成后再通过createFromParcel()方法将对象A从Parcel中还原回来。
实现Parcelable接口案例演示:
一般的步骤如下:
① implements Parcelable
② 重写writeToParcel方法,将你的对象序列化为一个Parcel对象,即:将类的数据写入外部提供的Parcel中,打包需要传递的数据到Parcel容器保存,以便从 Parcel容器获取数据
③ 重写describeContents方法,内容接口描述,默认返回0就可以
④ 实例化静态内部对象CREATOR实现接口Parcelable.Creator
代码案例:
/**
* 类描述:
* Created by lizhenya on 16/9/4.
*/
public class LocationInfo implements Parcelable {
private double longitude;
private double latitude;
private String locationName;
public LocationInfo() {
}
public LocationInfo(double latitude, double longitude, String locationName) {
this.latitude = latitude;
this.longitude = longitude;
this.locationName = locationName;
}
protected LocationInfo(Parcel in) {
longitude = in.readDouble();
latitude = in.readDouble();
locationName = in.readString();
}
public static final Creator<LocationInfo> CREATOR = new Creator<LocationInfo>() {
@Override
public LocationInfo createFromParcel(Parcel in) {
return new LocationInfo(in);
}
@Override
public LocationInfo[] newArray(int size) {
return new LocationInfo[size];
}
};
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public String getLocationName() {
return locationName;
}
public void setLocationName(String locationName) {
this.locationName = locationName;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeDouble(longitude);
parcel.writeDouble(latitude);
parcel.writeString(locationName);
}
}