文章目录

  • 一、前言:
  • 二、Serializable 接口
  • 三、Parcelable 接口
  • 四、两种接口怎么选择

一、前言:

本节主要讲解 IPC 中的基本概念,Serializable 接口与 Parcelable 接口。
这两个接口可以完成对象的序列化过程,当我们需要通过 Intent 和 Binder 传输数据时就需要使用 Serializable 与 Parcelable 。还有的时候我们需要把对象持久化到存储设备上或者通过网络传输给其他客户端,这个时候也需要使用这两个接口来完成对象的持久化,下面我们一一来介绍。

啥叫对象的持久化?不知道的看下面一句话:

持久化一般指将数据持久化保存,如存到数据库中或写到文件中

二、Serializable 接口

Serializable 是 Java所提供的一个序列化接口,这里提到了序列化,那什么叫序列化和反序列化呢?

序列化就是将 Java 对象转换成二进制文件数据的过程。这样说可能不是很明白,举个例子:如果把一个房子比作一个对象,要把这个做房子搬到另外一个地方的话,直接挪动是不现实的,但是可以将房子拆成一个个小零件运输,到了目的地在组装成房子,这样就容易多了,这其中 “拆解” 的过程就是序列化,“重新组装” 就是反序列化。

说到这里,怎么实现序列化呢?
只需要在类的声明中指定一个类似下面的标识即可自动实现默认的序列化过程。

private static final long serialVersionUID = 51906712373232662L;

全部代码:

import java.io.Serializable;public class User implements Serializable {private static final long serialVersionUID = 51906712373232662L;public int userId;public String userName;public boolean isMale;public User(int userId, String userName, boolean isMale) {this.userId = userId;this.userName = userName;this.isMale = isMale;}
}

对象的序列化和反序列化只需要采用 ObjectOutputStream 和 ObjectInputStream 即可轻松实现,如下:

 // 序列化过程,就是写的过程User user = new User(0, "Jack", true);ObjectOutputStream out;{try {out = new ObjectOutputStream(new FileOutputStream("user.txt"));out.writeObject(user);out.close();} catch (IOException e) {e.printStackTrace();}}// 反序列化过程,就是读的过程ObjectInputStream in;User newUser;{try {in = new ObjectInputStream(new FileInputStream("user.txt"));newUser = (User) in.readObject();in.close();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}

现在有个问题,serialVersionUID 是用来辅助序列化和反序列化过程的,原则上序列化后的数据中 serialVersionUID 只有和当前类的 serialVersionUID 相同才能够正常地被反序列化。不用它行不行,答案:不行。

serialVersionUID 的详细工作机制是这样的:序列化的时候系统会把当前的 serialVersionUID 写入序列化的文件中(也可能是其他中介),当反序列化的时候系统回去检测文件中的 serialVersionUID ,看它是否和当前类的 serialVersionUID 一致,如果一致就说明序列化类的版本和当前的版本是相同的,这个时候可以成功反序列化;否则就说明当前类和序列化的类相比发生了变化,这个时候是无法反序列化的,会报错。

再简单的说就是:反序列化时如果当前类有所改变,比如增加或者删除了某些成员变量,那么系统就会重新计算当前类的 hash 值并把它赋值给 serialVersionUID ,这个时候当前类的 serialVersionUID 就和序列化的数据中心的 serialVersionUID 不一致,于是反序列化失败,程序 crash。所以,我们可以明显感觉到 serialVersionUID 的作用。

Serializable 就介绍到这里了,再加一点比较重要的知识点:静态成员变量属于类不属于对象。所以不会参与序列化的过程,其次使用 transient 关键字编辑的成员变量不参与序列化过程。

三、Parcelable 接口

我们在 Android Studio 中写了一个类 User 实现 Parcelable 接口

public class User implements Parcelable {public int userId;public String userName;public boolean isMale;@Overridepublic int describeContents() {return 0;}@Overridepublic void writeToParcel(Parcel parcel, int i) {}
}

这个时候就会爆红,我们把鼠标放到 User 上面然后按住 "Alt + Enter"键会出现下图的情况,点击第一个 Add Parcelable Implementation
点击之后编辑器自动给我们写了序列化和反序列化过程,非常省事

我们看看全部代码:

import android.os.Parcel;
import android.os.Parcelable;public class User implements Parcelable {public int userId;public String userName;public boolean isMale;protected User(Parcel in) {userId = in.readInt();userName = in.readString();isMale = in.readByte() != 0;}// 反序列化public static final Creator<User> CREATOR = new Creator<User>() {@Overridepublic User createFromParcel(Parcel in) {return new User(in);}@Overridepublic User[] newArray(int size) {return new User[size];}};// 内容描述@Overridepublic int describeContents() {return 0;}// 序列化@Overridepublic void writeToParcel(Parcel parcel, int i) {parcel.writeInt(userId);parcel.writeString(userName);parcel.writeByte((byte) (isMale ? 1 : 0));}
}

Parcelable 的方法说明

方法 功能 标记位
createFromParcel(Parcel in) 从序列化后的对象中创建原始对象
newArray(int size) 创建指定长度的原始对象数组
User(Parcel in) 从序列化后的对象中创建原始对象
writeToParcel (Parcel out, int flags) 将当前对象写入序列化结构中,其中flags标识有两种值:0或者1(参见右侧标记位)。为1时标识当前对象需要作为返回值返回,不能立即释放资源,几乎所有情况都为0 PARCELABLE_WEITE_RETURN VALUE
describeContents 返回当前对象的内容描述。如果含有文件描述符,返回1(参见右侧标记位),否则返回0, 几乎所有情况都返回0 CONTENTS_FILE_DESCRIPTOR

四、两种接口怎么选择

既然 Parcelable 和 Serializable 都能实现序列化并且都可以用于 Intent 间的数据传递,通过二和三我们也知道他们之间的区别了,那么二者该怎么选择呢?

1.Serializable 是 Java 中的序列化接口,其使用起来开销比较大,序列化过程有很多 I/O 操作,所以在Java 中我们就采用 Serializable 接口。

2.Parcelable 是 Android 中的序列化方式,因此更适合用在 Android 平台上,它的缺点就是使用起来比较麻烦,但是它的效率很高,这是 Android 推荐的序列化方式,因此我们要首选 Parcelable。

3.Parcelable 将对象序列化到存储设备中或者将对象序列化后通过网络传输也都是可以的,但是这个过程会稍微复杂,在 Java 平台建议用 Serializable,在 Android 平台建议用 Parcelable 。
部分内容来自安卓开发艺术探索

Android --- Serializable 接口与 Parcelable 接口的使用方法和区别,怎么选择?相关推荐

  1. Serializable接口和Parcelable接口

    一.Serializable接口 在Java中,一般在定义实体类(entity class)时,会去实现Serializable接口,下面举例: 重点: 使用Serializable接口很简单,只需要 ...

  2. android 传递接口对象吗,android中Intent传递对象,需要实现Serializable接口或者Parcelable接口...

    Intent传递对象,有两种方法 1. 实现Serializable接口 类要生成序列化ID,并且不能是内部类 2. 实现Parcelable接口 参照Parcelable的doc文档 实现Seria ...

  3. Android中的Parcelable接口和Serializable用法和区别

    Parcelable接口: Interface for classes whose instances can be written to and restored from a Parcel. Cl ...

  4. Activity之间的数据传递—实现Parcelable接口

    一.单向传递数据和接收 1.可以传递数据类型 传递基本数据类型.字符串和对应的数组 传递Bundle(类似HashMap) 传递对象数据 传递Integer集合.String集合和parcelable ...

  5. Android中Parcelable接口用法 和 Serializable实现与Parcelabel实现的区别

    1. Parcelable接口 Interface for classes whose instances can be written to and restored from a Parcel. ...

  6. Android - Parcelable接口用法 和 与 Serializable 的区别

    android 中自定义的对象的序列化方法: implements Parcelable implements Serializable. 一 序列化原因: 永久性保存对象,保存对象的字节序列到本地文 ...

  7. Android中Parcelable接口用法

    --  通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射成你的对象.也可以将Parcel看成是一个流,通过writeToPa ...

  8. Android中的数据传递之Parcelable接口

    对于Android来说传递复杂类型,主要是将自己的类转换为基础的字节数组,Activity之间传递数据是通过Intent实现的. Android序列化对象主要有两种方法,实现Serializable接 ...

  9. Android 的Parcelable接口

    此文转载自http://www.cnblogs.com/renqingping/archive/2012/10/25/Parcelable.html 1. Parcelable接口 Interface ...

最新文章

  1. 083 HBase的完全分布式的搭建与部署,以及多master
  2. Java EE WEB工程师培训-JDBC+Servlet+JSP整合开发之10.Web_工程结构
  3. 百度超级链XChain(3)平台特点
  4. linux pppd源码下载_pppd源代码分析
  5. Java进阶高级程序员必备:深入浅出springboot+深入Java虚拟机
  6. php下载文件压缩包已经损坏或未知格式,这个压缩文件格式未知或者数据已经被损坏解决方法...
  7. Linux系统中使用shell判断磁盘是否格式化的方法
  8. 震撼!7月12日山东滨州,中科院向起电的雷暴云发射拖带金属导线专用火箭人工引雷!...
  9. UVA12771 LA6528 Disjoint water supply【并查集+DAG】
  10. javascript oo实现
  11. 小D课堂 - 新版本微服务springcloud+Docker教程_5-04 feign结合hystrix断路器开发实战下...
  12. 5个优化页面加载速度提高SEO排名的最佳实践
  13. 软件项目进度控制表(自制)
  14. BP神经网络算法及Matlab实现
  15. linux伊甸园论坛,Deepin2014壁纸大赛评审团——不断努力的Linux伊甸园
  16. 中国医大CT-YOUNG 闪讯和深澜并存的验证机制研究
  17. 手机浏览器一键跳转微信加好友和公众号关注的方法
  18. 他说,我可能以后不干安全了
  19. 知乎上关于ReactNative的评论汇总(网友们有才哟...)
  20. (六)1609.4协议详解

热门文章

  1. Android应用权限管理总结
  2. asp.net MVC iis6 虚拟主机兼容开发方式
  3. 【自然框架】分享 n级联动下拉列表框
  4. Fedora13安装Gnome-shell
  5. C++中的4个类型转换关键字
  6. 高速缓存系统之redis c++使用实例
  7. 网络开源框架之libevent使用实例
  8. OpneCV3特征提取及匹配SURF算法(一)——SURF概述与代码演示
  9. Windows下Caffe的学习与应用(三)——使用OpenCV3调用自己训练好的Caffe模型进行图像分类
  10. 购物车清除的php,php-如何清除废弃的woocommerce购物车