Android Parcel和Parcelable类
1. Parcel类
Parcel
主要用于在进程间通讯,传递数据。
Parcel
通过obtain()
静态方法获取,数据的存储和读取主要通过writeXXX()
和readXXX()
实现,marshall()
和unmarshall()
将数据序列化和反序列化,最后recycle()
回收资源。
public byte[] writeValue() {Parcel data = Parcel.obtain();try {data.writeInt(12);data.writeDouble(34.5);data.writeString("This is a string");return data.marshall();} finally {data.recycle();}
}public void readValue(byte[] bytes) {Parcel reply = Parcel.obtain();try {reply.unmarshall(bytes, 0, bytes.length);reply.setDataPosition(0);reply.readInt();reply.readDouble();reply.readString();} finally {reply.recycle();}
}
2. Parcelable类
Parcelable
是个接口,用于数据的传递。
在Parcel
中,存储Parcelable
数据,调用Parcelable.writeToParcel(Parcel, int)
方法。
public final void writeParcelable(Parcelable p, int parcelableFlags) {if (p == null) {writeString(null);return;}writeParcelableCreator(p);// Parcelable.writeToParcel方法p.writeToParcel(this, parcelableFlags);
}
而读取Parcelable
数据时,调用Creator
的子类,并调用createFromParcel()
方法来读取
public final <T extends Parcelable> T readParcelable(ClassLoader loader) {// 获得Parcelable中的CREATOR类Parcelable.Creator<?> creator = readParcelableCreator(loader);if (creator == null) {return null;}if (creator instanceof Parcelable.ClassLoaderCreator<?>) {Parcelable.ClassLoaderCreator<?> classLoaderCreator =(Parcelable.ClassLoaderCreator<?>) creator;return (T) classLoaderCreator.createFromParcel(this, loader);}return (T) creator.createFromParcel(this);
}public final Parcelable.Creator<?> readParcelableCreator(ClassLoader loader) {String name = readString();if (name == null) {return null;}Parcelable.Creator<?> creator;synchronized (mCreators) {HashMap<String,Parcelable.Creator<?>> map = mCreators.get(loader);if (map == null) {map = new HashMap<>();mCreators.put(loader, map);}// 如果有缓存,直接读取createcreator = 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 that the "+ "class implements Parcelable");}// 查看是否存在名字为CREATOR的静态属性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;
}
实现Parcelable
步骤
- 必须要
implement Parcelable
。 - 重写
describeContents()
方法。 - 重写
writeToParcel(Parcel, int)
方法。 - 实例化静态内部对象
CREATOR
实现接口Parcelable.Creator
。
ParcelableValue
类继承Parcelable
,
public class ParcelableValue implements Parcelable {private int i;private double d;private String s;public ParcelableValue(int i, double d, String s) {this.i = i;this.d = d;this.s = s;}public ParcelableValue(Parcel data) {i = data.readInt();d = data.readDouble();s = data.readString();}@Overridepublic int describeContents() {return 0;}@Overridepublic void writeToParcel(Parcel dest, int flags) {dest.writeInt(i);dest.writeDouble(d);dest.writeString(s);}public static final Creator<ParcelableValue> CREATOR = new Parcelable.Creator<ParcelableValue>() {@Overridepublic ParcelableValue createFromParcel(Parcel source) {return new ParcelableValue(source);}@Overridepublic ParcelableValue[] newArray(int size) {return new ParcelableValue[size];}};}
3. 与Serializable序列化比较
- 在使用内存的时候,
Parcelable
比Serializable
性能高。 Parcelable
不能使用在要将数据存储在磁盘上的情况
Android Parcel和Parcelable类相关推荐
- Android之Parcel和Parcelable
总结: Parcel 类是一个容器,能装各种类型的数据,并能在C/CPP底层传输. Parcel 可以在Binder 驱动为不同进程实现数据交互,为什么它能充当这样的角色呢? 系统设计使然.虽然不同进 ...
- Android源码分析 - Parcel 与 Parcelable
0. 相关分享 Android-全面理解Binder原理 Android特别的数据结构(二)ArrayMap源码解析 1. 序列化 - Parcelable和Serializable的关系 如果我们需 ...
- 包含c语言的序列化字符,Android Serializable与Parcelable原理与区别
一.序列化.反序列化是什么? (1) 名词解释 对象的序列化 : 把Java对象转换为字节序列并存储至一个储存媒介的过程. 对象的反序列化:把字节序列恢复为Java对象的过程. (2) 序列化详细解释 ...
- 【Binder 机制】AIDL 分析 ( 创建 AIDL 文件 | 创建 Parcelable 类 | AIDL 中使用 Parcelable 类 | 编译工程生成 AIDL 对应的Java源文件 )
文章目录 一.创建 AIDL 文件 1.创建 AIDL 目录 2.创建 AIDL 文件 3.创建 Parcelable 类 4.AIDL 目录下声明 Parcelable 类 5.AIDL 中使用 P ...
- [android] Serializable 和 Parcelable 区别
android 中自定义的对象序列化的问题有两个选择一个是Parcelable,另外一个是Serializable. 一 序列化原因: 1.永久性保存对象,保存对象的字节序列到本地文件中: 2.通过序 ...
- android 如何使用Parcelable接口
今天,简单讲讲android如何使用Parcelable接口传递数据. 这个其实也很简单,之前我写过博客将关于Serializable接口传递对象,实现Parcelable接口也是为了传递对象,但效率 ...
- Android Serializable与Parcelable原理与区别
2019独角兽企业重金招聘Python工程师标准>>> 一.序列化.反序列化是什么? (1) 名词解释 对象的序列化 : 把Java对象转换为字节序列并存储至一个储存媒介的过程. 对 ...
- Android | 序列化Serializable/Parcelable 使用总结
本文已同步发表于我的微信公众号,搜索 代码说 即可关注,欢迎与我沟通交流. 文章目录 一.什么是序列化?为什么要序列化?怎么进行序列化? 二.Serializable 2.1 序列化举例 2.2 重写 ...
- Android 快速实现Parcelable接口
Android序列化有两种方式, 实现Serializable, 这种直接 implements Serializable就好了. 另一种就是实现Parcelable 需要写一些代码. 好在有andr ...
最新文章
- 分享.NET开发中经常使用到的代码片段 完全从实际项目中提取出来,也可被反反复复的重复借用...
- 企业管理做不好的根源!「管理智慧」
- Python-TXT文本操作
- gitlab新增ssh
- 神策数据保险行业解决方案,正式上线官网!
- 产品经理,你来自江湖
- c位边上还有什么位_c位是什么意思?C位说法的由来是什么?c位旁边二个位置叫什么?...
- SQL练习题完整(做完你就是高手)
- 案例分析:你造吗?有个ORA-60死锁的解决方案
- paip.百度空间 JAVA程序发文总结
- MVC自定义路由的配置,必须把自己的路由写在前面
- 收集一些电子书下载的网站
- JAVA实现饭店点菜系统详解
- .7z文件 合并、解压
- oracle deadlock with TM lock in SX/SSX mode
- 如何删除iPhone或iPad上的所有照片
- 管理大规模容器集群能力包括_阿里巴巴大规模神龙裸金属 Kubernetes 集群运维实践...
- Eclipse开发工具的使用
- 2021年第十二届蓝桥杯软件类省赛python组试题及其解析。
- 新能源锂电池行业除杂工艺介绍