在我的Android应用程序中,我基本上有一个实现Parcelable
的类,其中一个需要从Parcel
读取和写入的字段是对抽象类的引用。实现Parcelable
。
这是抽象类及其具体实现之一:
public abstract AbstractClass1 implements Parcelable {
}
public class ConcreteClass1 extends AbstractClass1 {
private ConcreteClass1(Parcel in) {
this.setSomeData(in.readInt());
}
public static final Parcelable.Creator<ConcreteClass1> CREATOR =
new Parcelable.Creator<ConcreteClass1>() {
public ConcreteClass1 createFromParcel(Parcel in) {
return new ConcreteClass1 (in);
}
public ConcreteClass1[] newArray(int size) {
return new ConcreteClass1[size];
}
};
@Override
public int describeContents() { return 0; }
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.getSomeData());
}
}
到目前为止,我在其他Parcelable
类中需要读取和写入AbstractClass1
对Parcel
的引用。我不确定如何使CREATOR
工作:
public Class2 implements Parcelable {
private int data = 42;
private AbstractClass1 class1;
public Class2(AbstractClass1 c) { this.class1 = c; }
private Class2(Parcel in) {
this.data = in.readInt();
// this line is bad since it requires us to know about
// what concrete class is being set for class1. This
// class should only need to be aware of AbstractClass1
this.class1 = in.readParcelable(ConcreteClass1.class);
}
public static final Parcelable.Creator<Class2> CREATOR =
new Parcelable.Creator<Class2>() {
public Class2 createFromParcel(Parcel in) {
return new Class2(in);
}
public Class2[] newArray(int size) {
return new Class2[size];
}
};
@Override
public int describeContents() { return 0; }
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.data);
dest.writeInt(this.class1);
}
}
对于如何使用Parcelable
处理这个抽象类问题,是否有最佳实践?我理解Parcelable
并不是一个通用的序列化工具,但对于很多应用程序来说这似乎是一个重要的问题,让Parcelable
工作是非常必要的。如果用户按下后退按钮然后想要返回应用程序,因为需要保存应用程序的状态。我在CREATOR
上的特殊AbstractClass1
也不起作用,因为这个类不应该知道具体的实现。它应该是某种工厂模式吗?
答案 0 :(得分:1)
方法writeParcelable(Parcelable, int)
将适当的非抽象类的名称写入Parcel
(以及您在writeToParcel
方法中编写的数据)。
与此相反的是readParcelable(null)
。 readParcelable
首先读回类的名称,然后在调用Creator
Creator
方法之前能够从该类中获取正确的createFromParcel
对象。
readParcelable
的论据不是Class
,而是ClassLoader
。如果您通过了null
,则会使用默认的ClassLoader
。