简单的来说就是:在Intent或Bundle中无法直接放对象,必须把对象序列化为二进制流才行,传输完成后要进行反序列化,重新从流变为对象。
进行Android开发的时候,无法将对象的引用传给Activities或者Fragments,我们需要将这些对象放到一个Intent或者Bundle里面,然后再传递。简单来说就是将对象转换为可以传输的二进制流(二进制序列)的过程,这样我们就可以通过序列化,转化为可以在网络传输或者保存到本地的流(序列),从而进行传输数据 ,那反序列化就是从二进制流(序列)转化为对象的过程.
Parcelable是Android为我们提供的序列化的接口,Parcelable相对于Serializable的使用相对复杂一些,但Parcelable的效率相对Serializable也高很多,这一直是Google工程师引以为傲的,有时间的可以看一下Parcelable和Serializable的效率对比 Parcelable vs Serializable 号称快10倍的效率
用的时候要注意:
写构造方法的时候要写参数为Parcel的情况
要实现序列化、反序列化、描述这三个功能
描述很简单,没有特殊情况就返回0,目的是添加注释描述类
序列化要注意使用对于参数类型的write
用一个小例子说明一下:
public class People implements Parcelable {
private String mName;
private int mAge;
private boolean mGender;
private ArrayList<String> mJobs;
private Friend mFriend;
private ArrayList<Friend> mFriends= new ArrayList<>()
public People() {}
/**
* 描述
* 返回的是内容的描述信息
* 只针对一些特殊的需要描述信息的对象,需要返回1,其他情况返回0就可以
*
* @return
*/
@Override
public int describeContents() {
return 0;
}
/**
* 序列化
*
* @param dest
* @param flags
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mName);
dest.writeInt(mAge);
dest.writeByte((byte) (mGender ? 1 : 0));
dest.writeStringList(mJobs);
dest.writeParcelable(mFriend, flags);// 序列化对象的时候传入要序列化的对象和一个flag,这里的flag几乎都是0,除非标识当前对象需要作为返回值返回,不能立即释放资源
dest.writeTypedList(mFriends);
}
/**
* 负责反序列化
*/
public People(Parcel source) {
mName= source.readString();
mAge= source.readInt();
mGender= source.readByte() != 0;
mJobs= in.createStringArrayList();
mFriend= source.readParcelable(Friend.class.getClassLoader()); // 读取对象需要提供一个类加载器去读取,因为写入的时候写入了类的相关信息
mFriends.readTypedList(mFriends, Friend.CREATOR); //对应writeTypeList
}
private static final Creator<People> CREATOR = new Creator<People>() {
/**
* 从序列化对象中,获取原始的对象
* @param source
* @return
*/
@Override
public Album createFromParcel(Parcel source) {
return new People(source);
}
/**
* 创建指定长度的原始对象数组
* @param size
* @return
*/
@Override
public People[] newArray(int size) {
return new People[size];
}
};
}
下图是过程模型:
Parcelable过程模型
写入和读取集合有两种方式,
一是写入类的相关信息,然后通过类加载器去读取, –> writeList | readList;
二是不用类相关信息,创建时传入相关类的CREATOR来创建 –> writeTypeList | readTypeList | createTypedArrayList
第二种效率高一些
一定要注意如果有集合定义的时候一定要初始化
public ArrayList<T> demo = new ArrayList<>();
网友评论