将Parcelable的子类写入另一个Parcel
我有一个实现Parcelable
接口的类:
class A implements Parcelable { }
我有另一个类B
包含一个A
对象作为一个实例variables。 在B
类的writeToPacel
,我想将对象B
写入Parcel
:
class B implements Parcelable{ public void writeToParcel(Parcel dest, int flags) { dest.write ??? } }
我怎样才能写和读呢?
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); } }
如果你想读它使用这个
obj = in.readParcelable(A.class.getClassLoader());
处理这个避免reflection的更好方法是简单地调用目标types的静态创build器,如下所示:
this.amazingObject = AmazingObject.CREATOR.createFromParcel(in);
并使用this.amazingObject.writeToParcel(Parcel, int)
将其写入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); }
正如你所看到的那个方法的最后一个调用只是调用正确的Creator
但是在readParcelableCreator
里面,有很多的reflection,我们可以直接调用它来避免。
这个工具调用可能是有用的:
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); } }
该行:
obj = (A)in.readParcelable(A.class.getClassLoader());
应改为:
obj = (A)in.readParcelable(B.class.getClassLoader());
我遇到了同样的问题,并做了几次谷歌search,许多网页或教程build议我们使用A.class.getClassLoader()
因为我们正在铸造到A,但实际上是错误的,因为你会得到一个空值,我们必须使用B.class.getClassLoader()
因为codes are INSIDE class B
我只是不知道为什么,但它可以通过这种方式得到正确的A对象。
欢迎来评论和validation!