Android 序列化 (Serializable 和 Parcelable)
Serializable 是 Java 本身就支持的接口。
Parcelable 是 Android 特有的接口,效率比实现 Serializable 接口高效(可用于 Intent 数据传递,也可以用于进程间通信(IPC))。
Serializable 的实现,只需要 implements Serializable 即可。这只是给对象打了一个标记,系统会自动将其序列化。
Parcelabel 的实现,不仅需要 implements Parcelabel,还需要在类中添加一个静态成员变量 CREATOR,这个变量需要实现 Parcelable.Creator 接口。
Serializable 使用 I/O 读写存储在硬盘上,而 Parcelable 是直接在内存中读写。
Serializable 会使用反射,序列化和反序列化过程需要大量 I/O 操作,Parcelable 自己实现封送和解封( marshalled &unmarshalled)操作不需要用反射,数据也存放在 Native 内存中,效率要快很多
?? 实现 Serializable
import?java.io.Serializable;
public?class?UserSerializable?implements?Serializable?{
public?String?name;
public?int?age;
}
然后你会发现没有 serialVersionUID。
Android Studio 是默认关闭 serialVersionUID 生成提示的,我们需要打开 Setting,执行如下操作:
再次回到 UserSerializable 类,有个提示,就可以添加 serialVersionUID 了。
效果如下:
public?class?UserSerializable?implements?Serializable?{
private?static?final?long?serialVersionUID?=?1522126340746830861L;
public?String?name;
public?int?age?=?0;
}
?? 实现 Parcelable
Parcelabel 的实现,不仅需要实现 Parcelabel 接口,还需要在类中添加一个静态成员变量 CREATOR,这个变量需要实现 Parcelable.Creator 接口,并实现读写的抽象方法。如下:
public?class?MyParcelable?implements?Parcelable?{
private?int?mData;
public?int?describeContents()?{
return?0;
}
public?void?writeToParcel(Parcel?out,?int?flags)?{
out.writeInt(mData);
}
public?static?final?Parcelable.Creator<MyParcelable>?CREATOR
=?new?Parcelable.Creator<MyParcelable>()?{
public?MyParcelable?createFromParcel(Parcel?in)?{
return?new?MyParcelable(in);
}
public?MyParcelable[]?newArray(int?size)?{
return?new?MyParcelable[size];
}
};
private?MyParcelable(Parcel?in)?{
mData?=?in.readInt();
}
}
此时 Android Studio 给我们了一个插件可自动生成 Parcelable 。
?? 自动生成 Parcelable
==================
public?class?User?{
String?name;
int?age;
public?String?getName()?{
return?name;
}
public?void?setName(String?name)?{
this.name?=?name;
}
public?int?getAge()?{
return?age;
}
public?void?setAge(int?age)?{
this.age?=?age;
}
}
想进行序列化,但是自己写太麻烦了,这里介绍个插件操作简单易上手。
?? 先下载
?? 使用
?? 效果
public?class?User?implements?Parcelable?{
String?name;
int?age;
public?String?getName()?{
return?name;
}
public?void?setName(String?name)?{
this.name?=?name;
}
public?int?getAge()?{
return?age;
}
public?void?setAge(int?age)?{
this.age?=?age;
}
@Override
public?int?describeContents()?{
return?0;
}
@Override
public?void?writeToParcel(Parcel?dest,?int?flags)?{
dest.writeString(this.name);
dest.writeInt(this.age);
}
public?void?readFromParcel(Parcel?source)?{
this.name?=?source.readString();
this.age?=?source.readInt();
}
public?User()?{
}
protected?User(Parcel?in)?{
this.name?=?in.readString();
this.age?=?in.readInt();
}
public?static?final?Parcelable.Creator<User>?CREATOR?=?new?Parcelable.Creator<User>()?{
@Override
public?User?createFromParcel(Parcel?source)?{
return?new?User(source);
}
@Override
public?User[]?newArray(int?size)?{
return?new?User[size];
}
};
}
搞定。
写完了咱就运行走一波。
?? 使用实例
=======
?? Serializable
MainActivity.class
Bundle?bundle?=?new?Bundle();
UserSerializable?userSerializable=new?UserSerializable("SCC",15);
bundle.putSerializable("user",userSerializable);
Intent?intent?=?new?Intent(MainActivity.this,?BunderActivity.class);
intent.putExtra("user",bundle);
startActivity(intent);
BunderActivity.class
Bundle?bundle?=?getIntent().getBundleExtra("user");
UserSerializable?userSerializable=?(UserSerializable)?bundle.getSerializable("user");
MLog.e("Serializable:"+userSerializable.name+userSerializable.age);
日志:
2021-10-25?E/-SCC-:?Serializable:SCC15
?? Parcelable
MainActivity.class
Bundle?bundle?=?new?Bundle();
bundle.putParcelable("user",new?UserParcelable("SCC",15));
Intent?intent?=?new?Intent(MainActivity.this,?BunderActivity.class);
intent.putExtra("user",bundle);
startActivity(intent);
BunderActivity.class
Bundle?bundle?=?getIntent().getBundleExtra("user");
UserParcelable?u
serParcelable=?(UserParcelable)?bundle.getParcelable("user");
MLog.e("Parcelable:"+userParcelable.getName()+userParcelable.getAge());
日志:
2021-10-25?E/-SCC-:?Parcelable:SCC15
?? Parcelable 中使用泛型
===================
?? UserParcelable
public?class?UserParcelable<T?extends?Parcelable>?implements?Parcelable?{
private?String?name;
private?int?age;
private?T?data;
//...set/get 部分省略
public?T?getData()?{
return?data;
}
public?void?setData(T?data)?{
this.data?=?data;
}
public?UserParcelable(String?name,?int?age,?T?data)?{
this.name?=?name;
this.age?=?age;
this.data?=?data;
}
@Override
public?int?describeContents()?{
return?0;
}
@Override
public?void?writeToParcel(Parcel?dest,?int?flags)?{
dest.writeString(this.name);
dest.writeInt(this.age);
//这里:先保存这个泛型的类名
dest.writeString(data.getClass().getName());
dest.writeParcelable(this.data,?flags);
}
public?void?readFromParcel(Parcel?source)?{
this.name?=?source.readString();
this.age?=?source.readInt();
//这里
String?dataName?=?source.readString();
try?{
评论