Android(安卓)Parcel和Parcelable类
16lz
2021-01-26
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 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> map = mCreators.get(loader); if (map == null) { map = new HashMap<>(); mCreators.put(loader, map); } // 如果有缓存,直接读取create 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 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(); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(i); dest.writeDouble(d); dest.writeString(s); } public static final Creator CREATOR = new Parcelable.Creator() { @Override public ParcelableValue createFromParcel(Parcel source) { return new ParcelableValue(source); } @Override public ParcelableValue[] newArray(int size) { return new ParcelableValue[size]; } };}
3. 与Serializable序列化比较
- 在使用内存的时候,
Parcelable
比Serializable
性能高。 Parcelable
不能使用在要将数据存储在磁盘上的情况
更多相关文章
- Android之Service组件
- Android设置Dialog透明度、黑暗度方法
- RecyclerView 中 item 点击事件的优化
- cocos2d-x 3.0rc2中读取sqlite文件
- android获取各种路径的方法
- Android设置透明效果的三种方法
- Android使用SimpleAdapter
- Android(安卓)如何通过menu id来得到menu item 控件--binbinyang
- Android(安卓)平板 控制软键盘只弹出一半,自动盯着界面中EditText