我正在实现具有另一个Parcelable insde的Parcelable类。
在OuterParcelable类中:
@Override
public void writeToParcel(Parcel dest, int flags) {
Bundle tmp = new Bundle();
tmp.putParcelable("innerParcelable", mParcelable);
dest.writeBundle(tmp);
然后:
public OuterParcelable(Parcel parcel) {
super();
Bundle b = parcel.readBundle();
mParcelable = b.getParcelable("innerParcelable");
和
public OuterParcelable createFromParcel(Parcel in) {
return new OuterParcelable(in);
}
当我使用上面的代码重新创建对象时,我得到:
08-18 17:13:08.566: ERROR/AndroidRuntime(15520): Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: my.package.InnerParcelable
答案 0 :(得分:3)
将非基本属性存储为parcelable(可能为null)值的简洁方法。使用Parcel.writeValue()和readValue()。请参阅以下代码中的评论:
public class MyParcelableClass implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(getIntegerAttribute()); // getIntegerAttribute() returns Integer
dest.writeValue(getDoubleAttribute());
dest.writeValue(getMyEnumAttribute()); // getMyEnumAttribute() returns a user defined enum
dest.wrtieValue(getUserClassAttribute()); //UserClass must implement Parcelable in a similar fashion
}
private MyParcelableClass(Parcel in) {
setIntegerAttribute((Integer)in.readValue(null)); //pass null to use default class loader. Ok for Integer, String, etc.
setDoubleAttribute((Double)in.readValue(null)); //Cast to your specific attribute type
setEnumAttribute((MyEnum)in.readValue(null));
setUserClassAttribute((UserClass)in.readValue(UserClass.class.getClassLoader())); //Use specific class loader
}
@Override
public int describeContents() ...
public static final Parcelable.Creator<ParcelableLocationBean> CREATOR ...
}
像魅力一样工作。 writeValue()和readValue()封装处理可能的空值和类型检测。来自javadoc:
public final void writeValue(Object v)
展平通用对象 到一个包裹。给定的Object值当前可能是其中之一 以下类型:
null,String,Integer,...
String [], boolean [],...
任何实现Parcelable协议的对象。 ...
答案 1 :(得分:2)
为什么要将值放入Bundle?你是否在课堂上完全实现了这个行为?
public MyClass(Parcel in) {
readFromParcel(in);
}
//
// Parcelable Implementation
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(aParcelableClass, flags);
}
private void writeObject(Parcel dest, Object obj) {
if (obj != null) {
dest.writeInt(1);
dest.writeValue(obj);
} else {
dest.writeInt(0);
}
}
public void readFromParcel(Parcel in) {
aParcelableClass = in.readParcelable(ParcelableClass.class.getClassLoader());
}
private Object readObject(Parcel in) {
Object value = null;
if (in.readInt() == 1) {
value = in.readValue(null); // default classloader
}
return value;
}
public static final Parcelable.Creator<MyClass> CREATOR = new Parcelable.Creator<MyClass>() {
@Override
public MyClass createFromParcel(Parcel source) {
return new MyClass(source);
}
@Override
public MyClass[] newArray(int size) {
return new MyClass[size];
}
};
我添加了一些东西来使null值更容易处理,但原理是相同的。您需要@Override项目,构造函数和创建者。
如果您要读取和写入一个parcelable,如果您指定null作为类加载器,则会出现问题。