写点什么

Android 序列化 (Serializable 和 Parcelable)

用户头像
Android架构
关注
发布于: 2021 年 11 月 07 日
  • 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


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


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?{

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android 序列化(Serializable和Parcelable)