/**
* 描述: 描述 —— 序列化 —— 反序列化
* Parcelabel 与 Serializable 的区别:
* 1、在使用内存的时候, Parcelable 比 Serializable 性能高,所以推荐使用Parcelable;
* 2、Serializable 在序列化的时候会产生大量的临时变量,从而引起频繁的GC;
* 3、Parcelable 不能使用在将数据存储在磁盘的情况,因为在外界有变化的情况下,Parcelable不能很好的保证数据的持续性。
* 内存序列化上选择Parcelable, 存储到设备或者网络传输上选择Serializable(当然Parcelable也可以但是稍显复杂)
* 实例详解:参考https://www.jianshu.com/p/32a2ec8f35ae
*/
public class ShbBean implements Parcelable {
private String shbName;//旅游团名称
private String cityName;//旅游城市
private float price;//预算
private ArrayList<String> scenic_spot;//旅游景点
private CityBean cityBean;//城市属性
// 如果是集合,一定要初始化
private ArrayList<CityBean> citys = new ArrayList<>();//所有合适城市集合
public ShbBean(String shbName, String cityName, float price) {
this.shbName = shbName;
this.cityName = cityName;
this.price = price;
}
public ArrayList<CityBean> getCitys() {
return citys;
}
public void setCitys(ArrayList<CityBean> citys) {
this.citys = citys;
}
public ArrayList<String> getScenic_spot() {
return scenic_spot;
}
public void setScenic_spot(ArrayList<String> scenic_spot) {
this.scenic_spot = scenic_spot;
}
public CityBean getCityBean() {
return cityBean;
}
public void setCityBean(CityBean cityBean) {
this.cityBean = cityBean;
}
public String getShbName() {
return shbName;
}
public void setShbName(String shbName) {
this.shbName = shbName;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
//从流中读取对象 `
@Override
public String toString() {
return "ShbBean{" +
"shbName='" + shbName + '\'' +
", cityName='" + cityName + '\'' +
", price=" + price +
'}';
}
/**
* 3、负责反序列化
* 读取接口,目的是从Parcel中构造一个实现了Parcelable 的类的实例处理,因为实现类在这里是不可知的,所以需要
* 用到模板的方式,继承类名通过模板参数传入。
* 为了能实现模板参数的传入,这里定义Creator 嵌入接口,内含两个接口函数分别返回耽搁和多个继承类实例。
*/
public static final Creator<ShbBean> CREATOR = new Creator<ShbBean>() {
//从序列化的对象中创建原始对象
//实现从Parcel容器中读取传递数据值,封装成 Parcelable 对象返回逻辑层。从流中读取对象
@Override
public ShbBean createFromParcel(Parcel in) {
return new ShbBean(in);
}
//创建指定长度的原始对象数组
//供外部类反序列化本类数组使用。
@Override
public ShbBean[] newArray(int size) {
return new ShbBean[size];
}
};
protected ShbBean(Parcel in) {
shbName = in.readString();
cityName = in.readString();
price = in.readFloat();
//读取字符串集合
scenic_spot = in.createStringArrayList();
//读取对象需要提供一个类加载去读取,因为写的时候用了类的相关信息
cityBean = in.readParcelable(CityBean.class.getClassLoader());
/**
* 读取集合也分为两类,对应写入的两类
* 方法一:需要用相应的类加载器去获取。 —— 对应 writeList
*/
// in.readList(citys, CityBean.class.getClassLoader());
/**
* 方法二:需要用类的CREATOR去获取。 —— 对应 writeTypeList
*/
// in.readTypedList(citys, CityBean.CREATOR);
citys = in.createTypedArrayList(CityBean.CREATOR); // 对应 writeTypeList
/**
* 获取类加载器主要有几种方式:
*/
// getClass().getClassLoader();
// Thread.currentThread().getContextClassLoader();
// CityBean.class.getClassLoader();
}
/**
* 1、内容描述接口
*
* @return
*/
@Override
public int describeContents() {
return 0;
}
/**
* 2、负责序列化
* 写入接口函数,打包 —— 将对象序列化一个Parcel对象,即将类的数据写入外部提供的Parcel中,打包需要
* 传递的数据到Parcel容器保存,以便Parcel容器获取数据。
* 将你的对象写入流里面
*
* @param dest
* @param flags
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(shbName);
dest.writeString(cityName);
dest.writeFloat(price);
//序列化字符串集合
dest.writeStringList(scenic_spot);
//序列化对象的时候要传入flags , flags几乎都是0,除非标识当前对象需要作为返回值返回,不能立即释放资源
dest.writeParcelable(cityBean, flags);
/**
* 序列化集合两种方式,分别和上述两种反序列化方式对应。
*/
//这个方法把类的信息和数据都写入Parcel,以便将来能使用合适的类加载器重新构造类的实例,所以效率不高
// dest.writeList(citys);
//这个方法不会写入类的信息,取而代之的是:读取时必须能知道数据属于哪个类并传入正确的Parcelable.Creator
//来创建对象,而不是直接构造新的对象。
dest.writeTypedList(citys);
}
}
public class CityBean implements Parcelable {
private String district;//区
private String route;//路线
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
public String getRoute() {
return route;
}
public void setRoute(String route) {
this.route = route;
}
/**
* 反序列化
*/
protected CityBean(Parcel in) {
route = in.readString();
district = in.readString();
}
public static final Creator<CityBean> CREATOR = new Creator<CityBean>() {
@Override
public CityBean createFromParcel(Parcel in) {
return new CityBean(in);
}
@Override
public CityBean[] newArray(int size) {
return new CityBean[size];
}
};
@Override
public int describeContents() {
return 0;
}
//序列化
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(district);
dest.writeString(route);
}
}