基本上我的应用程序中有以下结构:
在没有抽象类ProjectItem
的情况下实现这样的结构会很简单,但在这种情况下,我不知道如何实现它。
抽象类ProjectItem
需要CREATOR
,因为它应该是可以分配的。 (喜欢
构造函数Project(Parcel in)中的in.readTypedList(mProjectItems, ProjectItem.CREATOR);
但事实上,CREATOR
只能出于逻辑原因在其派生类中实现。
那么,如何实现这个结构以保持类Project
可分隔?
修改
这是Project
的构造函数之一:
private Project(Parcel in) {
in.readTypedList(mProjectItems, ProjectItem.CREATOR);
}
但正如我已经说过,ProjectItem
不应该实施CREATOR
答案 0 :(得分:8)
我的解决方案类似于evertvandenbruel's。但我使用int识别具体类,以便我可以使用switch块。我还在静态getConcreteClass(Parcel)方法中使用了这个开关块。
AbstractClass.java
public abstract class AbstractClass implements Parcelable {
public static final int CLASS_TYPE_ONE = 1;
public static final int CLASS_TYPE_TWO = 2;
public static final Creator<AbstractClass> CREATOR = new Creator<AbstractClass>() {
@Override
public AbstractClass createFromParcel(Parcel source) {
return AbstractClass.getConcreteClass(source);
}
@Override
public AbstractClass[] newArray(int size) {
return new AbstractClass[size];
}
};
protected String mAbstractClassString;
public AbstractClass(String abstractClassString) {
mAbstractClassString = abstractClassString;
}
public AbstractClass(Parcel source) {
mAbstractClassString = source.readString();
}
public static AbstractClass getConcreteClass(Parcel source) {
switch (source.readInt()) {
case CLASS_TYPE_ONE:
return new ConcreteClassOne(source);
case CLASS_TYPE_TWO:
return new ConcreteClassTwo(source);
default:
return null;
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mAbstractClassString);
}
@Override
public String toString() {
return "Parent String: " + mAbstractClassString + '\n';
}
}
ConcreteClassOne.java
public class ConcreteClassOne extends AbstractClass {
private String mString;
public ConcreteClassOne(String abstractClassMemberString, String string) {
super(abstractClassMemberString);
mString = string;
}
public ConcreteClassOne(Parcel source) {
super(source);
mString = source.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(CLASS_TYPE_ONE);
super.writeToParcel(dest, flags);
dest.writeString(mString);
}
@Override
public String toString() {
return super.toString().concat("Child String: " + mString);
}
}
ConcreteClassTwo.java
public class ConcreteClassTwo extends AbstractClass {
private String mString;
private int mInt;
public ConcreteClassTwo(String abstractClassString, String string, int anInt) {
super(abstractClassString);
mString = string;
mInt = anInt;
}
public ConcreteClassTwo(Parcel source) {
super(source);
mString = source.readString();
mInt = source.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(CLASS_TYPE_TWO);
super.writeToParcel(dest, flags);
dest.writeString(mString);
dest.writeInt(mInt);
}
@Override
public String toString() {
String string = super.toString();
for (int i = 0; i < mInt; i++) {
string = string.concat("Child String: " + mString + '\n');
}
return string;
}
}
答案 1 :(得分:2)
所选答案(来自evertvandenbruel的帖子)中有一个错误。当只有一个子类被分配时,正确的代码必须考虑parceling,而不仅仅是超类对象的列表。
所有其他代码应该是相同的,关键是你必须在所有创建者的类型变量中读取(参见下面的代码)。否则,在尝试取消分类子类对象时会出现排序问题
例如:
package com.example.parcelable_example.model;
import android.os.Parcel;
import android.os.Parcelable;
public class Cat extends Animal{
public Cat(String name){
super(name, "Cat");
}
public int describeContents() {
return this.hashCode();
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(getType());
super.writeToParcel(dest, flags);
}
public Cat(Parcel source) {
super(source);
}
public static final Parcelable.Creator<Cat> CREATOR = new Parcelable.Creator<Cat>() {
public Cat createFromParcel(Parcel in) {
/** DO NOT FORGET THIS!!! **/
type = in.readString();
return new Cat(in);
}
public Cat[] newArray(int size) {
return new Cat[size];
}
};
}
答案 2 :(得分:1)
这个问题来自一个错误的假设。
这是原始帖子的引文。
抽象类ProjectItem需要一个CREATOR,因为它应该是 可包裹的。
实际上,由于超类是抽象的,因此不必定义CREATOR。
这是演示该方法的最小示例。
/* Super class */
abstract class SuperClass
implements Parcelable {
protected SuperClass(Parcel in) {
mSuperId = in.readLong();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(mSuperId);
}
}
/* Sub class */
public class SubClass
extends SuperClass {
protected SubClass(Parcel in) {
super(in);
mSubId = in.readLong();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeLong(mSubId);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<SubClass> CREATOR = new Creator<SubClass>() {
@Override
public SubClass createFromParcel(Parcel in) {
return new SubClass(in);
}
@Override
public SubClass[] newArray(int size) {
return new SubClass[size];
}
};
}
/* Usage */
class AnotherClass {
void aMethod() {
Bundle args = new Bundle();
args.putParcelable("EXTRA_SUPER_CLASS", subClassObject);
}
}
答案 3 :(得分:0)
public abstract class A implements Parcelable {
private int a;
protected A(int a) {
this.a = a;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(a);
}
protected A(Parcel in) {
a = in.readInt();
}
}
public class B extends A {
private int b;
public B(int a, int b) {
super(a);
this.b = b;
}
public static final Parcelable.Creator<B> CREATOR = new Parcelable.Creator<B>() {
public B createFromParcel(Parcel in) {
return new B(in);
}
public B[] newArray(int size) {
return new B[size];
}
};
public int describeContents() {
return 0;
}
}