6

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

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

有一个类 B 是从类 A 扩展而来的。类 B 有额外的成员数据,但它们都不需要 parceled。基本上,B 类的可打包数据与 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和接受 a 的构造函数,然后Parcel才将其传递回 A . 其他一切都是一样的。唯一使它不同的是类的名称。它首先打破了继承的目的。

例如,如果有另一个类 C 扩展 B,我需要做同样的事情:

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。

4

2 回答 2

2

这有点复杂,但我能想到的唯一方法涉及反射 - 如果所有子类都有一个构造函数,该构造函数接受 aParcel然后调用super(parcel),你可以将类名作为包的一部分 - 然后在你的 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;
}

请注意,这主要是临时写的,可能需要在运行之前进行一些调整(我确定它缺少检查的异常处理程序) - 但希望这个想法很清楚

于 2012-10-09T23:48:18.187 回答
-1

我已经实现了 JRaymond 描述的解决方案并且它有效。这有点复杂,因为它涉及一些反思,但我希望它对其他人有所帮助。现在任何可打包的类都应该扩展这个实现可打包的 GlobalParcelable 类。

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

于 2013-09-27T20:28:14.217 回答