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序列化比较

  • 在使用内存的时候,ParcelableSerializable性能高。
  • Parcelable不能使用在要将数据存储在磁盘上的情况

更多相关文章

  1. Android之Service组件
  2. Android设置Dialog透明度、黑暗度方法
  3. RecyclerView 中 item 点击事件的优化
  4. cocos2d-x 3.0rc2中读取sqlite文件
  5. android获取各种路径的方法
  6. Android设置透明效果的三种方法
  7. Android使用SimpleAdapter
  8. Android(安卓)如何通过menu id来得到menu item 控件--binbinyang
  9. Android(安卓)平板 控制软键盘只弹出一半,自动盯着界面中EditText

随机推荐

  1. Ubuntu下 下载Android(安卓)源码(来自官网
  2. android 读取指定路径数据库文件
  3. Android(安卓)transformClassesWithDexFo
  4. Android(安卓)之安装APK
  5. 【问题】Android(安卓)Studio3.1.2 Rejec
  6. Android(安卓)TV开发中所有的遥控器按键
  7. Android(安卓)Jetpack Components of Vie
  8. android Gallery3D效果
  9. Getting Smack working with Android(安
  10. Android(安卓)坐标