Можно ли отправить общий класс?

Я пытаюсь создать public class MyClass<T extends Parcelable> implements Parcelable . У меня возникли проблемы с внедрением Parcelable . Можно ли создать общий класс, который реализует Parcelable ? (Заметим, что T ограничен, так что он также должен реализовывать Parcelable ).

У меня возникает проблема с тем, что интерфейс Parcelable требует статической переменной: public static final Parcelable.Creator<MyParcelable> CREATOR . Таким образом, я не могу сделать public static final Parcelable.Creator<MyClass<T>> CREATOR потому что MyParcelable<T> нестатический.

Андре

Solutions Collecting From Web of "Можно ли отправить общий класс?"

У меня были аналогичные проблемы с реализацией Parcelable в классе с общим, первый вопрос был таким же, как и то, что вы испытывали:

Таким образом, я не могу сделать публичный статический окончательный Parcelable.Creator> CREATOR, потому что MyParcelable нестатический.

Второй должен был прочитать объект Parcelable, вам нужен доступ к ClassLoader который не может быть ClassLoader из T из-за стирания типа .

Следующий класс – это адаптация класса, который я использую в производстве, который преодолевает обе проблемы. Примечание. Я не тестировал этот класс специально, поэтому дайте мне знать, есть ли у вас какие-либо проблемы.

 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 } 

Да, ты можешь. Вам просто нужно сохранить имя класса или загрузчик классов во время построения вашего объекта подкласса, а затем вы можете передать его во время операции чтения / записи посылок.

Пошаговые инструкции:

Шаг 1 . Сохраните имя класса, которое распространяется из вашего класса Generic следующим образом:

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

Шаг 2 . Любые классы, которые простираются от вашего общего класса, должны указывать имя класса во время его построения следующим образом:

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

Шаг 3 . В своем общем классе вы можете читать / записывать имена классов в getClassLoader () следующим образом:

 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 } 

}

Запишите имя класса элемента данных в пакет и затем прочитайте его, чтобы создать его загрузчик классов. Пример,

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