目录
什么是序列化
数据的序列化是指,将我们程序开发的对象类,转化为计算机存储的最小单位,字节序列。
数据的反序列化是指:将计算机中的字节序列转换为我们开发中的对象实体类。
为什么需要序列化
比如我们在Java程序开发过程中,声明一个Person对象,包括(姓名,身高,性别,职业)等属性,当我们程序执行,Person属性赋值时,这个对象是存在于内存当中的,而内存的数据在断电或者程序结束后,数据便会丢失,为了防止数据不丢失,我们可以通过序列化的方式存储在计算机外存当中,等下次需要的时候,再从外存取。而序列化的方式大大提高了数据传输的效率。也为数据的持久化存储提供了可能。
序列化的方式
Java:Serializable
Android:Parcelable,
1:重写writetoParcel(in:Parcel,flag:Int)和describeContents()方法
2:创建内部静态属性CREATOR,实现Parcelable.Creator<T>()接口,实现createFromParcel和newArray方法
ide一般会自己生成,需要我们结合业务补充属性。
防止安卓序列化失败,取不到值,要保证构造方法内的属性顺序及个数和writetoParcel的保持一致
原理:通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射成你的对象。也可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面,在通过createFromParcel从流里读取对象,只不过这个过程需要你来实现,因此写的顺序和读的顺序必须一致
区别:
Java的Serializabel接口,使用简单,但是效率较低,在使用过程中会产生大量的临时对象,引发GC。
Android的Parcelable接口,需要重写方法,更适合较为复杂的数据,效率较高,原理在于Parcelable接口会把对象分解为intent可以传递的数据类型。
实例
Serializable的用法:
实体类Student实现Serializable接口
data class Student(val name:String):Serializable{
var height:Float = 0.0f
var age:Int = 0
var sex:Int = 0
override fun toString(): String {
return "Student(name='$name', height=$height, age=$age, sex=$sex)"
}
}
在A Activity中,可以通过intent的putExtra()传递
val zs = Student("zhangsan")
zs.height =152.5f
zs.age = 16
zs.sex=1
val intent = Intent(this,MainActivity2::class.java)
intent.putExtra("data",zs)
startActivity(intent)
在B Activity中,通过getSerializableExtra()强转为对象 接收使用
val zhangsan = intent.getSerializableExtra("student") as Student
println("student name:${zhangsan.name}-age:${zhangsan.age}-height:${zhangsan.height}")
Parcelable的用法:
实体类Person
1:实现Parcelable接口,重写writeToPalcel(),describeContents()
2:实例化静态内部对象CREATOR,实现Parcelable.Creator<T>()接口
data class Person(val type:Int):Parcelable {
var name = ""
var age = 0
constructor(parcel: Parcel) : this
(type = parcel.readInt()) {
//构造方法的变量及顺序应该和writeToParcel保持一致,不可不写
name = parcel.readString().toString()
age = parcel.readInt()
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeInt(type)
parcel.writeString(name)
parcel.writeInt(age)
}
override fun describeContents(): Int {
return 0
}
override fun toString(): String {
return "Person(type=$type, name='$name', age=$age)"
}
companion object CREATOR : Parcelable.Creator<Person> {
override fun createFromParcel(parcel: Parcel): Person {
return Person(parcel)
}
override fun newArray(size: Int): Array<Person?> {
return arrayOfNulls(size)
}
}
}
在A Activity当中,通过bundle的putParcelable()传递实体类对象
val zs = Person(1)
zs.name = "zhangsan"
zs.age = 16
val intent = Intent(this,MainActivity2::class.java)
val bundle = Bundle()
bundle.putParcelable("person",zs)
intent.putExtra("data",bundle)
startActivity(intent)
在B Activity中,通过bundle的getParcelableExtra<T>()接收使用
val data = intent.getBundleExtra("data")
val person = data?.getParcelable<Person>("person")
if (person != null)
println("name:${person.name},age:${person.age}")
Java-List集合以及数组类型的序列化:
public class bean implements Parcelable {
private List<DataBean> data;
private int errorCode;
private String errorMsg;
// private int[] numberArray;
protected bean(Parcel in) {
//List集合写法
data = in.readArrayList(DataBean.class.getClassLoader());
errorCode = in.readInt();
errorMsg = in.readString();
//int[]数组写法
// numberArray = in.createIntArray();
}
public static final Creator<bean> CREATOR = new Creator<bean>() {
@Override
public bean createFromParcel(Parcel in) {
return new bean(in);
}
@Override
public bean[] newArray(int size) {
return new bean[size];
}
};
public List<DataBean> getData() {
return data;
}
public void setData(List<DataBean> data) {
this.data = data;
}
public int getErrorCode() {
return errorCode;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeList(data);
dest.writeInt(errorCode);
dest.writeString(errorMsg);
// dest.writeIntArray(numberArray);
}
public static class DataBean implements Parcelable{
private String desc;
private int id;
private String imagePath;
private int isVisible;
private int order;
private String title;
private int type;
private String url;
protected DataBean(Parcel in) {
desc = in.readString();
id = in.readInt();
imagePath = in.readString();
isVisible = in.readInt();
order = in.readInt();
title = in.readString();
type = in.readInt();
url = in.readString();
}
public static final Creator<DataBean> CREATOR = new Creator<DataBean>() {
@Override
public DataBean createFromParcel(Parcel in) {
return new DataBean(in);
}
@Override
public DataBean[] newArray(int size) {
return new DataBean[size];
}
};
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getImagePath() {
return imagePath;
}
public void setImagePath(String imagePath) {
this.imagePath = imagePath;
}
public int getIsVisible() {
return isVisible;
}
public void setIsVisible(int isVisible) {
this.isVisible = isVisible;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(desc);
dest.writeInt(id);
dest.writeString(imagePath);
dest.writeInt(isVisible);
dest.writeInt(order);
dest.writeString(title);
dest.writeInt(type);
dest.writeString(url);
}
}