Android基础-序列化

191 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

简介

序列化(serialization)在计算机科学的资料处理中,是指将数据结构或对象状态转换成可取用格式(例如存成文件,存于缓冲,或经由网络中发送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程。依照序列化格式重新获取字节的结果时,可以利用它来产生与原始对象相同语义的副本。对于许多对象,像是使用大量引用的复杂对象,这种序列化重建的过程并不容易。面向对象中的对象序列化,并不概括之前原始对象所关系的函数。这种过程也称为对象编组(marshalling)。从一系列字节提取数据结构的反向操作,是反序列化(也称为解编组、deserialization、unmarshalling)

定义

  • 序列化:将执行对象转化为可传输的字节序列,该过程便是序列化。
  • 反序列化:把可传输的字节还原为对应执行对象,该过程便是反序列化。

序列化的目的

  1. 在系统底层,数据的传输形式都是简单的字节序列,如果要进行进程通信(注意不是特指进程间,进程内也是),首先需要将数据序列化。
  2. 跨平台传递数据都是需要将数据序列化,如网络传输,网络数据存储等等

序列化和字节序列区别

本质上是两个东西,字节序列是对象经过序列化协议序列化之后的产物,序列化就是针对对象转化为字节序列的过程。有点拗口,理解重点词就好。

实现方式

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方式

  1. 添加对 Parcelable 的支持,将以下 Gradle 插件添加到应用的 build.gradle.kts 文件中
plugins {
    id("kotlin-parcelize")
}
  1. 使用 @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,毕竟设备原因效率至上。