¿Es posible distribuir una clase genérica?

Estoy intentando crear public class MyClass<T extends Parcelable> implements Parcelable . Tengo problemas para implementar Parcelable . ¿Es posible crear una clase genérica que implemente Parcelable ? (Tenga en cuenta que T está limitado de modo que también debe implementar Parcelable ).

Estoy teniendo problemas con el hecho de que la interfaz Parcelable requiere una variable estática : public static final Parcelable.Creator<MyParcelable> CREATOR . Por lo tanto, no puedo hacer public static final Parcelable.Creator<MyClass<T>> CREATOR MyParcelable<T> porque MyParcelable<T> no es estadístico.

André

Tuve problemas similares con la implementación de Parcelable en una clase con un genérico, el primer problema era el mismo que lo que estaba experimentando:

Por lo tanto, no puedo hacer public static final Parcelable.Creator> CREATOR porque MyParcelable no es estadístico.

El segundo era leer en un objeto Parcelable que usted necesita el acceso al ClassLoader que no se puede conseguir de T debido al borrado del tipo .

La clase de abajo es una adaptación de una clase que estoy utilizando en la producción que supera ambos problemas. Nota: No he probado específicamente esta clase, así que avísame si tienes algún problema.

 public class TestModel<T extends Parcelable> implements Parcelable { private List<T> items; private String someField; public List<T> items() { return items; } public void setItems(List<T> newValue) { items = newValue; } public String someField() { return someField; } public void setSomeField(String newValue) { someField = newValue; } //region: Parcelable implementation public TestModel(Parcel in) { someField = in.readString(); int size = in.readInt(); if (size == 0) { items = null; } else { Class<?> type = (Class<?>) in.readSerializable(); items = new ArrayList<>(size); in.readList(items, type.getClassLoader()); } } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(someField); if (items == null || items.size() == 0) dest.writeInt(0); else { dest.writeInt(items.size()); final Class<?> objectsType = items.get(0).getClass(); dest.writeSerializable(objectsType); dest.writeList(items); } } public static final Parcelable.Creator<TestModel> CREATOR = new Parcelable.Creator<TestModel>() { public TestModel createFromParcel(Parcel in) { return new TestModel(in); } public TestModel[] newArray(int size) { return new TestModel[size]; } }; //endregion } 

Sí tu puedes. Sólo tiene que almacenar el nombre de la clase o el cargador de clases durante la construcción de su objeto de subclase y luego puede pasarlo durante la operación de lectura / escritura del parcelable.

Instrucciones paso a paso:

Paso 1 . Almacene el nombre de la clase que se extiende desde su clase genérica de la siguiente manera:

 public abstract class GenericClass<T> implements Parcelable { private String className; 

Paso 2 . Cualquier clase que se extienda desde su clase genérica debe especificar el nombre de la clase durante su construcción como esto:

 public class MyClass extends GenericClass<MyClass> { public MyClass () { super(); setClassName(MyClass.class.getName()); // Generic class setter method } 

Paso 3 . En su clase genérica, puede leer / escribir sus nombres de clase a getClassLoader () así:

 public abstract class GenericClass<T> implements Parcelable { private String className; T myGenericObject; protected MyClass (Parcel in) { super(in); this.className = in.readString(); ClassLoader classLoader; try { classLoader = Class.forName(this.className).getClassLoader(); } catch (ClassNotFoundException e) { e.printStackTrace(); } myGenericObject = in.readParcelable(classLoader); //... Other class members can go here } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeString(className); //... Other class members can go here } 

}

Escriba el nombre de la clase de miembro genérico de datos en el paquete y luego vuelva a leerlo para crear su cargador de clases. Ejemplo,

 public class MyClass<T> implements Parcelable { T data; @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(data.getClass().getName()); dest.writeParcelable((Parcelable) data, 0); } private MyClass(Parcel in) { final String className = in.readString(); try { data = in.readParcelable(Class.forName(className).getClassLoader()); } catch (ClassNotFoundException e) { Log.e("readParcelable", className, e); } } 
  • ¿Cómo leer y escribir Enum en paquete en Android?
  • Paso de arraylist de objetos entre actividades
  • Herencia parcelable: clase abstracta - ¿QUÉ CREADOR?
  • ¿Cómo hacer que un objeto sea accesible para todas las actividades de un programa Android?
  • Limitación de tamaño en adjunto ¿Parcelable?
  • Restauración de la vista SavedState lanza ClassNotFoundException al desmarcar la vista principal SavedState
  • ¿Cómo hacer una interfaz parcelable?
  • Lectura y escritura de matriz de números enteros a paquete
  • ¿Por qué utilizar parcelable cuando se puede realizar la misma tarea utilizando variables estáticas?
  • Android Parcelable y Serializable
  • Parcelable, ¿qué es newArray para?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.