6

これはここSOで数回尋ねられましたが、私の場合は少し異なります。

Parcelable を実装するクラス A があります。クラス A には、パーセル可能なメンバー データが含まれています。独自の、 、、および を受け入れるコンストラクターをCREATOR実装しています。writeToParcel()describeContents()Parcel

クラス A から拡張されたクラス B があります。クラス B には追加のメンバー データがありますが、いずれも分割する必要はありません。基本的に、クラス B のパーセル可能なデータはクラス A と同じです。B をバンドルに入れ、それを別のアクティビティに渡して読み戻そうとすると、ClassCastException が発生します。それは予想通りだと思います。

少し試行錯誤した後、クラス B をパーセル可能にするために、少なくとも次の 2 つのことを実装する必要があります。

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 から拡張された約 6 つ以上のクラスがあり、すべて B と同じ問題を抱えています。それらのそれぞれが独自の staticCREATORと a を受け入れるコンストラクターを追加し、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 自体を実装するように要求することもできます。

4

2 に答える 2

2

これは少し複雑ですが、私がオフハンドで考えることができる唯一の方法はリフレクションを含みます - すべてのサブクラスに を受け取り、Parcelそれを呼び出すコンストラクタがあるsuper(parcel)場合、クラス名をパーセルの一部にすることができます - そして createFromParcel メソッドでA の:

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 に答える