Android 序列化Serializable和Parcelable使用和区别

一:Serializable

1.什么是序列化

将一个类对象转换成可存储,可传输状态的过程。

2.什么是Serializable接口

一个对象序列化的接口,一个类只有实现了Serializable接口,它的对象才能被序列化。

3.为什么要序列化对象

1.把对象转换为字节序列的过程称为对象的序列化

2.把字节序列恢复为对象的过程称为对象的反序列化

4.序列化用途

1.想把对象的状态信息通过网络进行传输

2.需要把对象持久化存储,存储在文件,数据库等public class User implements Serializable {

private static final long serialVersionUID = 1L;

private String name;

private 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;

}

}

当我跟进去,发现Serializable是一个空接口,一个接口什么都没有,我们可以将它理解成一个标识接口例如:在课堂上有位学生遇到一个问题,于是举手向老师请教,这时老师帮他解答,那么这位学生的举手其实就是一个标识,自己解决不了问题请教老师帮忙解决。在Java中的这个Serializable接口其实是给jvm看的,通知jvm,我不对这个类做序列化了,你(jvm)帮我序列化就好了。

5.为什么要定义serialVersionUID变量

从说明中可以看出,如果我们没有自己申明一个serialVersionUID变量,接口会默认生成一个serialVersionUID

*但是强烈建议用户自定义一个serialVersionUID,因为默认的serialVersionUID对于class的细节非常敏感,反序列化时可能会导致

InvalidClassException这个异常。*

5.transient关键字

用来表示一个成员变量不是该对象序列化的一部分。当一个对象被序列化的时候,transient型变量的值不包括在序列化结果中。注:static修饰的静态变量天然的就是不可序列化的private static final long serialVersionUID = 1L;

private String name;

private transient int age;

transient关键字只能修饰变量,而不能修饰方法和类。

被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null。

二:Parcelable

Parcelable是Android为我们提供的序列化的接口,Parcelable的效率相对于Serializable也高许多。

Parcelable不能使用在要将数据存储在磁盘上情况

在内存中使用Parcelable性能优于Serializablepublic class User implements Parcelable {

private String name;

private int age;

public User(String name, int age) {

this.name = name;

this.age = age;

}

/**

* 从序列化后的对象中创建原始数据*/

protected User(Parcel in) {

name = in.readString();

age = in.readInt();

}

/**

* 序列化:将当前对象写入序列化结构中

*/

@Override

public void writeToParcel(Parcel dest, int flags) {

dest.writeString(name);

dest.writeInt(age);

}

/**

* 当前对象的内容描述,存在文件描述符时返回1,其余全返回0

*/

@Override

public int describeContents() {

return 0;

}

/**

* 反序列化

*/

public static final Creator CREATOR = new Creator() {

/**

* 将序列化对象中创建原始数据*/

@Override

public User createFromParcel(Parcel in) {

return new User(in);

}

/**

* 创建指定长度的原始对象数组*/

@Override

public User[] newArray(int size) {

return new User[size];

}

};

@Override

public String toString() {

return "User{" +

"name='" + name + ''' +

", age=" + age +

'}';

}

}

1.Parcel英文译为包裹,Android采用这个词表示封装消息的数据。这个通过IBinder通信的消息载体。Parcel用来存放数据的内存(RAM),而不是永久介质。//获取一个Parcel容器

Parcel parcel=Parcel.obtain();

//需要序列化的对象

User user=new User("mike",13);

//把对象写入Parcel

parcel.writeParcelable(user,0);

//Parcel读写共用一个位置计数,这里一定要重置一下当前的位置

parcel.setDataPosition(0);

//读取Parcel

User user1=parcel.readParcelable(User.class.getClassLoader());

Log.d("LoginActivity",user1.toString());

调用parcel.writeParcelable(user,0);源码解析public final void writeParcelable(@Nullable Parcelable p, int parcelableFlags) {

//判断p是否为空

if (p == null) {

writeString(null);

return; }

//先写入P的类名(user就是p类类名)

writeParcelableCreator(p);

//调用我们重写的writeToParcel方法,按顺序写入

p.writeToParcel(this, parcelableFlags);

}

/** @hide */

@UnsupportedAppUsage

public final void writeParcelableCreator(@NonNull Parcelable p) {

//写入p类的类名

String name = p.getClass().getName();

writeString(name);

}

调用parcel.readParcelable(User.class.getClassLoader());源码解析public final T readParcelable(@Nullable ClassLoader loader) {

//调用readParcelableCreator

//这时我们获取就是我们自定义的CREATOR

Parcelable.Creator> creator = readParcelableCreator(loader);

if (creator == null) {

return null;

}

// 判断当前creator是不是Parcelable.ClassLoaderCreator>的实例

if (creator instanceof Parcelable.ClassLoaderCreator>) {

//如果是的话,,我们调用reateFromParcel(this, loader)

Parcelable.ClassLoaderCreator> classLoaderCreator =

(Parcelable.ClassLoaderCreator>) creator;

return (T) classLoaderCreator.createFromParcel(this, loader);

}

//调用我们自定义的CREATOR中重写的createFromParcel方法

return (T) creator.createFromParcel(this);

}public final Parcelable.Creator> readParcelableCreator(@Nullable ClassLoader loader) {

//首先把类名读取出来

String name = readString();

if (name == null) {

return null;

}

Parcelable.Creator> creator;

//mCreators做了一下缓存,如果之前某个classloader把一个parcelable的Creator获取过

//那么就不需要通过反射去查找了

synchronized (mCreators) {

HashMap> map = mCreators.get(loader);

if (map == null) {

map = new HashMap<>();

mCreators.put(loader, map);

}

creator = map.get(name);

if (creator == null) {

try {

// If loader == null, explicitly emulate Class.forName(String) "caller

// classloader" behavior. ClassLoader parcelableClassLoader =

(loader == null ? getClass().getClassLoader() : loader);

// Avoid initializing the Parcelable class until we know it implements

// Parcelable and has the necessary CREATOR field. http://b/1171613. Class> parcelableClass = Class.forName(name, false /* initialize */,

parcelableClassLoader);

if (!Parcelable.class.isAssignableFrom(parcelableClass)) {

throw new BadParcelableException("Parcelable protocol requires subclassing "

+ "from Parcelable on class " + name);

}

Field f = parcelableClass.getField("CREATOR");

if ((f.getModifiers() & Modifier.STATIC) == 0) {

throw new BadParcelableException("Parcelable protocol requires "

+ "the CREATOR object to be static on class " + name);

}

Class> creatorType = f.getType();

if (!Parcelable.Creator.class.isAssignableFrom(creatorType)) {

// Fail before calling Field.get(), not after, to avoid initializing

// parcelableClass unnecessarily. throw new BadParcelableException("Parcelable protocol requires a "

+ "Parcelable.Creator object called "

+ "CREATOR on class " + name);

}

creator = (Parcelable.Creator>) f.get(null);

}

catch (IllegalAccessException e) {

Log.e(TAG, "Illegal access when unmarshalling: " + name, e);

throw new BadParcelableException(

"IllegalAccessException when unmarshalling: " + name);

}

catch (ClassNotFoundException e) {

Log.e(TAG, "Class not found when unmarshalling: " + name, e);

throw new BadParcelableException(

"ClassNotFoundException when unmarshalling: " + name);

}

catch (NoSuchFieldException e) {

throw new BadParcelableException("Parcelable protocol requires a "

+ "Parcelable.Creator object called "

+ "CREATOR on class " + name);

}

if (creator == null) {

throw new BadParcelableException("Parcelable protocol requires a "

+ "non-null Parcelable.Creator object called "

+ "CREATOR on class " + name);

}

map.put(name, creator);

}

}

return creator;

}

android 保存 parcelable对象,Android 使用序列化Serializable和Parcelable相关推荐

  1. android 序列化 xml serializable,关于Android中的序列化Serializable和Parcelable的学习

    简单地说,"序列化"就是将运行时的对象状态转换成二进制,然后保存到流,内存或者通过网络传输给其他端. 两者最大的区别在于 存储媒介的不同,Serializable使用 I/O 读写 ...

  2. Android的序列化(Serializable和Parcelable)

    [齐天的博客]转载请注明出处(万分感谢!): https://blog.csdn.net/qijinglai/article/details/80813423 前言 Android中要实现对象持久化或 ...

  3. android parcelable 对象,Android实现Parcelable对象序列化的实例

    Android实现Parcelable对象序列化的实例 bundle.putParcelable可以实现传递对象,但是这个对象的类必须实现Parcelable接口才能够使用. 下面是一个简单的在Act ...

  4. 【Android基础】序列化 Serializable vs Parcelable

    Serializable public class SerializableDeveloper implements SerializableString name;int yearsOfExperi ...

  5. 序列化Serializable、Parcelable

    序列化的概念: 所谓序列化就是将对象变成二进制流,便于存储和传输. 为什么要序列化和反序列化? 当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本.图片.音频.视频等, 而这些数据都会以二 ...

  6. 序列化-Serializable和Parcelable的简单介绍

    序列化的本质 序列化是一种用来处理对象流的机制.序列化是为了解决在对对象流进行读写操作时所引发的问题. 序列化:将java对象转换成字节序列的过程,字节码可以保存到数据库.内存.文件等,也可用于网络传 ...

  7. android sharedpreferences 存储对象,android中SharedPreferences实现存储用户名功能

    1. 简介 SharedPreferences是一种轻型的数据存储方式,通过key-value键值对的方式将数据存储在xml文件中,常用于存储简单的配置信息. 2. 使用方式 2.1 获取Shared ...

  8. android 高德坐标对象,android: 高德地图

    分为地图,定位,搜索(我还没做导航功能) 建议采用gradle方式集成 添加依赖 在project/build.gradle文件下添加jcenter的仓库地址 allprojects { reposi ...

  9. android 获取对话框对象,Android 基本Dialog和自定义Dialog

    Android 基本Dialog和自定义Dialog Dialog类是对话框的基类,但你应该避免直接实例化Dialog ,可以使用子类 1.AlertDialog 此对话框可以显示标题,最多三个按钮, ...

最新文章

  1. 《你必须掌握的Entity Framework 6.x与Core 2.0》正式出版感想
  2. 极光推送后台php接口,极光推送Jpush(v2)接口 服务端PHP版本的REST API推送类
  3. 【SDOI2017】天才黑客
  4. Oracle 查看sql语句执行计划方法
  5. 计算机游戏有哪几种,这些游戏你玩过几个? 你认为最经典的电脑游戏有哪些?
  6. Linux性能调优集合
  7. python多重继承_Python多重继承
  8. 小米笔记本 镜像_小米笔记本Air 13.3原装出厂WIN10 2004 ISO镜像下载
  9. centos下安装teamview
  10. Panabit标准版免费版功能限制
  11. 一元三次方程求解(求根) - 盛金公式法
  12. 基于深度学习股票预测系统
  13. 设计模式六大原则详解
  14. 《VR/AR技术与应用》笔记 001
  15. 浏览器Chrome被hao123劫持亲测最有效方式-(Lin)
  16. java玫瑰花代码_玫瑰花c语言代码
  17. 2015年9月20日
  18. 基于中台的公共图书馆数据服务研究
  19. Mysql常用类型和字段属性
  20. Mathematica入门

热门文章

  1. python数据分析报告范文_Python数据分析求解题
  2. LDCT图像重建论文——Eformer: Edge Enhancement based Transformer for Medical Image Denoising
  3. 虾米播播音乐墙html,WordPress音乐播放器插件Hermit X(支持网易云、QQ音乐、虾米等)...
  4. 期货突破法进场是等突破K走完再进场还是突破瞬间就进场?
  5. 目标检测到目标跟踪 -- Faster R-CNN 观测器
  6. 最大似然估计、最大后验概率估计和贝叶斯估计
  7. Skr-Eric的Mysql课堂(一)——Mysql的介绍和基本SQL命令
  8. codeblocks使用教程
  9. amCharts图形控件清空图表内数据
  10. dnc无线服务器,重庆dnc服务器地址