Parcelable和继承

6

这个问题在 SO 上已经被问了几次,但我的情况有点不同。

我有一个实现 Parcelable 的 A 类。A 类包含一些可分拣的成员数据。它有自己的 CREATOR 并实现了 writeToParcel()describeContents() 和一个接受 Parcel 的构造函数。

B 类继承自 A 类。B 类有额外的成员数据,但它们都不需要被 parcelable。基本上,B 类的 parcelable 数据与 A 类相同。如果我尝试将 B 放入 Bundle 中,将其传递到另一个 Activity,并读取它回来,那么我会得到 ClassCastException。我想这是可以预料的。

经过一番试错,为了使 B 类可分拣,我必须至少实现以下两个内容:

public static final Parcelable.Creator<B> CREATOR
        = new Parcelable.Creator<B>() {
    public B createFromParcel(Parcel source) {
        return new B(source);
    }

    public B[] newArray(int size) {
        return new B[size];
    }
};

public B(Parcel in) throws JSONException {
    super(in);
}

所以我的关注点在于此。有大约半打或更多的类从A继承,并且都像B一样存在同样的问题。每一个类都必须添加自己的静态CREATOR和接受Parcel的构造函数,只是为了将其传回A,这似乎很愚蠢。其他所有内容都是相同的。唯一使它不同的是类的名称。这完全违背了使用继承的初衷。
例如,如果还有另一个从B继承的C类,我需要做同样的事情:
public static final Parcelable.Creator<C> CREATOR
        = new Parcelable.Creator<C>() {
    public C createFromParcel(Parcel source) {
        return new C(source);
    }

    public C[] newArray(int size) {
        return new C[size];
    }
};

public C(Parcel in) throws JSONException {
    super(in);
}

有没有一些聪明的技巧可以在Java中自动化这个过程?也许使用某种泛型?如果没有其他方法,我可能会删除继承关系,并要求每个类自己实现Parcelable。


我有点晚了,但是这是我处理的方式:http://stackoverflow.com/a/20018463/362298 - Ricardo
2个回答

2

这有点复杂,但我能想到的唯一方式涉及到反射 - 假设所有的子类都有一个接受Parcel并调用super(parcel)的构造函数,你可以将类名作为parcel的一部分 - 然后在A的createFromParcel方法中:

public A createFromParcel(Parcel source) {
    Class clazz = Class.forName(source.readString());
    Class[1] paramTypes = { Parcel.class }; 
    Constructor ctor = clazz.getConstructor(paramTypes);
    A myA = (A) ctor.newInstance(source);
    return myA;
}

请注意,这是即兴写作的,可能需要进行一些微调才能运行(我确定它缺少checked exception handlers) - 但希望这个想法是清晰的。

-1

我已经实现了JRaymond所描述的解决方案,它可以正常工作。虽然它涉及到一些反射,但它有点复杂,但我希望它能帮助其他人。现在,任何可被打包的类都应该扩展这个实现了parcelable的GlobalParcelable类。

https://github.com/awadalaa/Android-Global-Parcelable


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接