Android Serializable与Parcelable原理与区别
2019独角兽企业重金招聘Python工程师标准>>>
一、序列化、反序列化是什么?
(1) 名词解释
对象的序列化 : 把Java对象转换为字节序列并存储至一个储存媒介的过程。
对象的反序列化:把字节序列恢复为Java对象的过程。
(2) 序列化详细解释
对象的序列化涉及三个点关键点:Java对象、字节序列、存储。
1. Java对象的组成?
Java对象包含变量与方法。但是序列与反序列化仅处理Java变量而不处理方法,序列与反序列化仅对数据进行处理。
2. 什么是字符序列?
字符序列是两个词,字符是在计算机和电信领域中,字符(Character)是一个信息单位。数学上,序列是被排成一列的对象(或事件)。
《字符-维基百科》 , 《序列-维基百科》 说白了就是连续排列的多个字符的集合。类似于1A165613246546
3. 存储
字符序列需要保存到一个地方,可以是硬盘也可以是内存。
简单说法是:序列化把当前对象信息保存下来。反序列化刚好相反的操作。
二、Java对象与Java对象序列化的区别?
Java对象存在的前提必须在JVM运行期间存在,如果想在JVM非运行的情况下或者在其他机器JVM上获取指定Java对象,在现有Java对象的机制下都不可能完成。
与Java对象不同的是,如果对Java对象执行序列化操作,因为原理是把Java对象信息保存到存储媒介,所以可以在以上Java对象不可能存在的两种情况下依然可以使用Java对象。
三、为什么要使用序列化、反序列化?
根据以上对序列化、反序列化的理解,这个疑问可以翻译成,为什么需要把对象信息保存到存储媒介中并之后读取出来?
因为二中的解释,开发中有在JVM非运行的情况下或者在其他机器JVM上获取指定Java对象的需求。
四、Android 中Serializable与Parcelable区别?
两种都是用于支持序列化、反序列化话操作,两者最大的区别在于存储媒介的不同,Serializable使用IO读写存储在硬盘上,而Parcelable是直接在内存中读写,很明显内存的读写速度通常大于IO读写,所以在Android中通常优先选择Parcelable。
Serializable不是当前关注的焦点,不过可以查看《Java序列化算法透析》这篇文章中实现一个简单的Serializable例子,查看序列化生成的IO文件,并且以16进制读取并一一解释每一个16进制数字的含义。
五、Parcelable举例
在Android中实现Parcelable接口的类可以支持序列与反序列化,以下是一个实现的举例:
1. 实现Parcelable接口
2. 添加实体属性
3. 覆写writeToParcel(Parcel dest, int flags)方法,指定写入Parcel类的数据。
4. 创建Parcelable.Creator静态对象,有两个方法createFromParcel(Parcel in)与newArray(int size),前者指定如何从Parcel中读取出数据对象,后者创建一个数组。
5. 覆写describeContents方法,默认返回0。
public class Gril implements Parcelable {private int mAge; // 年龄private boolean mSexy; // 是否性感@Overridepublic void writeToParcel(Parcel dest, int flags) {dest.writeInt(mAge);dest.writeByte((byte) (mSexy ? 1 : 0));}public static final Parcelable.Creator
六、Parcelable原理
从上面的例子中可以看出,具体的写入(dest.writeInt(mAge);)与读取(gril.mAge = in.readInt();)都是针对Parcel对象进行的操作,下面贴出的是Parcle 读写int类型数据的定义。
public final class Parcel {....../*** Write an integer value into the parcel at the current dataPosition(),* growing dataCapacity() if needed.*/public final native void writeInt(int val);/*** Read an integer value from the parcel at the current dataPosition().*/public final native int readInt();......
}
从上面代码可以看出都是native方法说明都是使用JNI,其具体位置在system/frameworks/base/core/jni/android_util_Binder.cpp ,以下也仅以int类型读写为例
static void android_os_Parcel_writeInt(JNIEnv* env, jobject clazz, jint val)
{Parcel* parcel = parcelForJavaObject(env, clazz);if (parcel != NULL) {const status_t err = parcel->writeInt32(val);if (err != NO_ERROR) {jniThrowException(env, java/lang/OutOfMemoryError, NULL);}}
}static jint android_os_Parcel_readInt(JNIEnv* env, jobject clazz)
{Parcel* parcel = parcelForJavaObject(env, clazz);if (parcel != NULL) {return parcel->readInt32();}return 0;
}
从上面可以看出都会调用Parcel实现且分别调用writeInt32与readInt32函数,接着来看看具体实现。位置:/system/frameworks/base/libs/binder/Parcel.cpp
status_t Parcel::writeInt32(int32_t val)
{return writeAligned(val);
}template
以下4点摘自《探索Android中的Parcel机制(上)》
有兴趣的朋友可以自己读一下,不难理解,这里把基本的思路总结一下:
1. 整个读写全是在内存中进行,主要是通过malloc()、realloc()、memcpy()等内存操作进行,所以效率比JAVA序列化中使用外部存储器会高很多;
2. 读写时是4字节对齐的,可以看到#define PAD_SIZE(s) (((s)+3)&~3)这句宏定义就是在做这件事情;
3. 如果预分配的空间不够时newSize = ((mDataSize+len)*3)/2;会一次多分配50%;
4. 对于普通数据,使用的是mData内存地址,对于IBinder类型的数据以及FileDescriptor使用的是mObjects内存地址。后者是通过flatten_binder()和unflatten_binder()实现的,目的是反序列化时读出的对象就是原对象而不用重新new一个新对象。
七、序列化反序列化Parcelable实验?
1. 任何实体类都需要复写Parcelable接口吗?
2. 如果子类新增属性,需要复写父类writeToParcel与CREATOR吗?
3. writeToParcel 与 createFromParcel 对变量的读写前后顺序可以不一致吗,会出现什么结果?
4. 读写Parcelable对象(写操作dest.writeParcelable(obj, flags); 读操作in.readParcelable(ObjectA.class.getClassLoader()); )
5. 读写Parcelable对象数组
dest.writeParcelableArray(mClassNameList.toArray(new ClassName[mClassNameList.size()]), flags);Parcelable[] parcelableArr = in.readParcelableArray(ClassName.class.getClassLoader());
ArrayList
转载于:https://my.oschina.net/u/593225/blog/402629
Android Serializable与Parcelable原理与区别相关推荐
- 包含c语言的序列化字符,Android Serializable与Parcelable原理与区别
一.序列化.反序列化是什么? (1) 名词解释 对象的序列化 : 把Java对象转换为字节序列并存储至一个储存媒介的过程. 对象的反序列化:把字节序列恢复为Java对象的过程. (2) 序列化详细解释 ...
- [android] Serializable 和 Parcelable 区别
android 中自定义的对象序列化的问题有两个选择一个是Parcelable,另外一个是Serializable. 一 序列化原因: 1.永久性保存对象,保存对象的字节序列到本地文件中: 2.通过序 ...
- android 保存 parcelable对象,Android 使用序列化Serializable和Parcelable
Android 序列化Serializable和Parcelable使用和区别 一:Serializable 1.什么是序列化 将一个类对象转换成可存储,可传输状态的过程. 2.什么是Serializ ...
- Android中Intent/Bundle的通信原理及大小限制(Parcelable原理及与Serializable的区别)
我们知道可以通过Intent和bundle在activity或fragment间进行通信,那么这个通信是如何实现的. 通过intent的bundle的源码可以看到它们都是实现了Parcelable, ...
- Android --- Serializable 接口与 Parcelable 接口的使用方法和区别,怎么选择?
文章目录 一.前言: 二.Serializable 接口 三.Parcelable 接口 四.两种接口怎么选择 一.前言: 本节主要讲解 IPC 中的基本概念,Serializable 接口与 Par ...
- android 序列化 xml serializable,关于Android中的序列化Serializable和Parcelable的学习
简单地说,"序列化"就是将运行时的对象状态转换成二进制,然后保存到流,内存或者通过网络传输给其他端. 两者最大的区别在于 存储媒介的不同,Serializable使用 I/O 读写 ...
- Android的序列化(Serializable和Parcelable)
[齐天的博客]转载请注明出处(万分感谢!): https://blog.csdn.net/qijinglai/article/details/80813423 前言 Android中要实现对象持久化或 ...
- Android中的Serializable和Parcelable序列化
Serializable和Parcelable接口都可以完成对象的序列化过程,在Android中当我们需要通过Intent和Binder传输数据时,我们要传输的对象就需要使用Serializable和 ...
- 简析Java中的Serializable与Android中的Parcelable序列化
文章目录 关于序列化 Serializable 简述原理 怎么使用 Parcelable Parcelable的实现原理 "包装公司"Parcel 装包 拆包 小结 Parcela ...
最新文章
- 影像组学视频学习笔记(11)-支持向量机(SVM)(理论)、Li‘s have a solution and plan.
- pygame简单的俄罗斯方块游戏和简单的打字游戏
- boost::geometry::intersects用法的测试程序
- 影响用户体验的4个因素
- 解决 用户'sa'登录失败。错误:18456 问题
- MySQL DEBUG_SYNC 的简单分析与测试
- python是什么课程-请问自学 Python 有必要买课程吗?
- Javascript语言精粹--The Excellence in Javascript
- 酒浓码浓 - js / 前端 / 支付宝,微信合并二维码功能
- npz文件转为npy_numpy文件存取-npz,npy
- IJCAI 2021 | 面向睡眠阶段分类的多模态显著性波形检测网络
- 硬盘格式化怎么操作 硬盘格式化后数据还在吗
- 搜索引擎优化系统知名乐云seo_北京网络优化知名乐云seo
- wps excel 表格给一列数据添加相同的内容的方法
- matlab画图三维立体,matlab的三维图形绘制
- MySQL的多表查询及习题练习
- 模板类的特例化(具体化)
- 童年汇老师教你如何给宝宝选玩具
- VSCode远程开发 Resolver error: Error: Failed to install the VS Code Server
- 影流之主——stm32OLED显示一张图片方法基于战舰
热门文章
- linux 通过虚拟ip出路由器,linux模拟路由器实验
- ef导入oracle数据类型不正确,EF Core操作Oracle踩坑记
- 鸿蒙系统和中标麒麟系统关系,操作系统有哪些 先有鸿蒙后有麒麟V10 为5G时代量身定做...
- java 嵌套listview_ListView嵌套GridView使用详解
- websocket中发生数据丢失_node.js – Websocket传输可靠性(重新连接期间Socket.io数据丢失)...
- java实例分析宠物商店_java实例分析:宠物商店.ppt
- SQLAlchemy 基本使用
- numpy 创建数组
- C++语言动态内存管理介绍和示例
- linux下pip安装模块失败,Linux pip包安装错误