将Parcelable的子类写入另一个Parcel

use*_*o01 65 android parcelable

我有一个实现Parcelable接口的类:

class A implements Parcelable {

}
Run Code Online (Sandbox Code Playgroud)

我有另一个类B包含一个A对象作为实例变量.在writeToPacel内部类B,我想写对象BParcel:

class B implements Parcelable{

    public void writeToParcel(Parcel dest, int flags) {
        dest.write ??? 
    }
}
Run Code Online (Sandbox Code Playgroud)

我怎么写和读它?

con*_*ius 164

class B implements Parcelable{
//lets assume you have A as a data member 

A obj;
public void writeToParcel(Parcel dest, int flags) {

        dest.writeParcelable(obj , flags);

    }
}
Run Code Online (Sandbox Code Playgroud)

如果你想阅读它使用这个

 obj = in.readParcelable(A.class.getClassLoader());
Run Code Online (Sandbox Code Playgroud)

  • 不需要铸造:) (6认同)
  • 你可以更精确:`obj =(A)in.<A> readParcelable(A.class.getClassLoader());` (4认同)

pab*_*sco 11

处理这种避免反射的更好方法是简单地调用目标类型中的静态创建者,如下所示:

this.amazingObject = AmazingObject.CREATOR.createFromParcel(in);
Run Code Online (Sandbox Code Playgroud)

并将其写入Parcelable使用this.amazingObject.writeToParcel(Parcel, int)

在内部,当readParcelable(ClassLoader)发生这种情况时:

public final <T extends Parcelable> T readParcelable(ClassLoader loader) {
    Parcelable.Creator<T> creator = readParcelableCreator(loader);
    if (creator == null) {
        return null;
    }
    if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
        return ((Parcelable.ClassLoaderCreator<T>)creator).createFromParcel(this, loader);
    }
    return creator.createFromParcel(this);
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的那样,该方法的最后一次调用只是调用正确的,Creator但在内部readParcelableCreator有很多反射,我们可以通过直接调用它来避免.

此实用程序调用可能很有用:

import android.os.Parcel;
import android.os.Parcelable;

public class Parcels {

    public static void writeBoolean(Parcel dest, Boolean value) {
        dest.writeByte((byte) (value != null && value ? 1 : 0));
    }

    public static Boolean readBoolean(Parcel in){
        return in.readByte() != 0;
    }

    public static void writeParcelable(Parcel dest, int flags, Parcelable parcelable) {
        writeBoolean(dest, parcelable == null);
        if (parcelable != null) {
            parcelable.writeToParcel(dest, flags);
        }
    }

    public static <T extends Parcelable> T readParcelable(Parcel in, Parcelable.Creator<T> creator) {
        boolean isNull = readBoolean(in);
        return isNull ? null : creator.createFromParcel(in);
    }

}
Run Code Online (Sandbox Code Playgroud)