2012-10-09 14 views
5

Zostało to zadane kilka razy tutaj na SO, ale mój przypadek jest nieco inny.Paczkomat i Dziedziczenie

Mam klasę A, która implementuje Parcelable. Klasa A zawiera niektóre dane członków, które można podzielić. Ma własną CREATOR i implementuje writeToParcel(), describeContents() i konstruktora, który akceptuje Parcel.

Istnieje klasa B, która rozciąga się od klasy A. Klasa B zawiera dodatkowe dane członków, ale żadna z nich nie musi być zapakowana. Zasadniczo dane działek klasy B są takie same jak w przypadku klasy A. Jeśli spróbuję umieścić B w pakiecie, przekazać go do innej aktywności i odczytać ją, otrzymam wyjątek ClassCastException. Sądzę, że to jest oczekiwane.

Po trochę prób i błędów, aby uczynić klasy B parcelable, muszę wdrożyć przynajmniej te dwie rzeczy:

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); 
} 

Więc moim problemem jest to. Istnieje około pół tuzina klas, które rozciągają się od A i wszystkie mają ten sam problem co B. Wydaje się to głupie, że każdy z nich musi dodać własny statyczny CREATOR i konstruktor, który akceptuje Parcel, tylko po to, aby go przekazać do A. Wszystko inne jest identyczne. Jedyną różnicą jest nazwa klasy. W pierwszej kolejności bije na cel posiadanie spadku.

Na przykład, jeśli istnieje inna klasa C, który rozszerza B, muszę zrobić to samo:

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); 
} 

Czy istnieje jakiś sprytnych technik w języku Java, aby zautomatyzować ten proces? Być może używając jakiegoś rodzaju? Jeśli nie ma innego sposobu, równie dobrze mogę po prostu usunąć linię dziedziczenia i wymagać, aby każda klasa sama wdrażała Parcelable.

+0

jestem trochę późno, ale tutaj jest to traktowane jak ja: http://stackoverflow.com/a/20018463/362298 –

Odpowiedz

2

Jest to trochę skomplikowane, ale to jedyny sposób mogę myśleć offhand polega odbicie - Pod warunkiem, wszystkie podklasy mieć konstruktora, że ​​trwa Parcel które następnie wywołuje super(parcel), można zrobić nazwa klasy część działki - następnie w metodzie 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; 
} 

Zauważ, że ten został napisany w dużej mierze od mankietu i może wymagać trochę szczypanie, zanim skończy (wiem na pewno, że brakuje sprawdzonych procedur obsługi wyjątków) - ale mam nadzieję, że pomysł jest wyczyść

-1

Zaimplementowałem rozwiązanie des spakowany przez JRaymonda i działa. To trochę skomplikowane, ponieważ wymaga refleksji, ale mam nadzieję, że pomoże komuś innemu. Teraz każda klasa, która jest paczkowana, powinna rozszerzyć tę klasę GlobalParcelable, która implementuje paczkę.

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