一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情。
简介
序列化(serialization)在计算机科学的资料处理中,是指将数据结构或对象状态转换成可取用格式(例如存成文件,存于缓冲,或经由网络中发送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程。依照序列化格式重新获取字节的结果时,可以利用它来产生与原始对象相同语义的副本。对于许多对象,像是使用大量引用的复杂对象,这种序列化重建的过程并不容易。面向对象中的对象序列化,并不概括之前原始对象所关系的函数。这种过程也称为对象编组(marshalling)。从一系列字节提取数据结构的反向操作,是反序列化(也称为解编组、deserialization、unmarshalling)
定义
- 序列化:将执行对象转化为可传输的字节序列,该过程便是序列化。
- 反序列化:把可传输的字节还原为对应执行对象,该过程便是反序列化。
序列化的目的
- 在系统底层,数据的传输形式都是简单的字节序列,如果要进行进程通信(注意不是特指进程间,进程内也是),首先需要将数据序列化。
- 跨平台传递数据都是需要将数据序列化,如网络传输,网络数据存储等等
序列化和字节序列区别
本质上是两个东西,字节序列是对象经过序列化协议序列化之后的产物,序列化就是针对对象转化为字节序列的过程。有点拗口,理解重点词就好。
实现方式
JAVA Serializable方式
- 实现
import java.io.Serializable;
public class XSerializable implements Serializable {
private static final long serialVersionUID = 1522895340746830861L;
public String name;
}
- 使用
MultiProcessActivityA.class
Bundle bundle = new Bundle();
XSerializable xSerializable = new XSerializable("namename");
bundle.putSerializable("name",xSerializable);
Intent intent = new Intent(MultiProcessActivityA.this, MultiProcessActivityB.class);
intent.putExtra("name",bundle);
startActivity(intent);
MultiProcessActivityB.class
Bundle bundle = getIntent().getBundleExtra("name");
XSerializable xSerializable = (XSerializable) bundle.getSerializable("name");
Android Parcelable方式
- 实现
public class XParcelable implements Parcelable {
private String name;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
public static final Parcelable.Creator<XParcelable> CREATOR
= new Parcelable.Creator<XParcelable>() {
public XParcelable createFromParcel(Parcel in) {
return new XParcelable(in);
}
public XParcelable[] newArray(int size) {
return new XParcelable[size];
}
};
private XParcelable(Parcel in) {
name = in.readInt();
}
}
- 使用
MultiProcessActivityA.class
Bundle bundle = new Bundle();
bundle.putParcelable("name",new XParcelable("namename"));
Intent intent = new Intent(MultiProcessActivityA.this, MultiProcessActivityB.class);
intent.putExtra("name",bundle);
startActivity(intent);
MultiProcessActivityB.class
Bundle bundle = getIntent().getBundleExtra("name");
UserParcelable userParcelable= (UserParcelable) bundle.getParcelable("name");
kotlin便捷使用Parcelable方式
- 添加对 Parcelable 的支持,将以下 Gradle 插件添加到应用的
build.gradle.kts文件中
plugins {
id("kotlin-parcelize")
}
- 使用 @Parcelize 为类添加注解时,系统会自动生成一个 Parcelable 实现
import kotlinx.parcelize.Parcelize
@Parcelize
data class XParcelable(val name: String):Parcelable
注意:
@Parcelize 要求在主要构造函数中声明所有序列化属性。该插件会针对每个属性发出警告,并在类正文中声明一个后备字段。此外,如果主构造函数的某些参数不是属性,就不能应用 @Parcelize。
Serializable和Parcelable的区别
SerializableJava语言封装的接口,Parcelable是Android封装的专用接口。Serializable在使用时相对简单,仅需要为对象生成对应随机的标记,系统会帮忙自动序列化,Parcelable要复杂一些,主要是需要添加静态成员变量CREATOR,实现Parcelable.Creator接口。Serializable会使用反射,使用I/O读写存储都在硬盘上,无论是序列化还是反序列化都存在大量I/O操作。而Parcelable是直接在内存中读写。所以相对而言Parcelable的效率更高效。
总结
Android上应该尽量采用Parcelable,毕竟设备原因效率至上。