2015-02-17 2 views
8

У меня есть абстрактный класс A, который реализует Parcelable.Возможное наследование: абстрактный класс - Какой СОЗДАТЕЛЬ?

У меня есть класс B и класс C, которые оба продлят A. Как я могу сделать их обоснованными?

Из-за причин я мог бы связать его и предоставить CREATOR как в A, так и в B, как это предлагается во многих сообщениях. Но так как у меня есть другие объекты, которые хранят в A-B-C классы и реализацию Parcelable themselfes, что подход, кажется, не работает, потому что, когда я хочу, чтобы передать ArrayList из A я бы использовать CREATOR в типизированном списке

ArrayList<A> elements = new ArrayList<>(); 
in.readTypedList(elements , B.CREATOR); // B.CREATOR? C.CREATOR??? 

Что явно не имеет смысла. Итак, как я могу правильно сделать A Parcelable?

I.e Я хочу сделать этот класс Parcelable, чтобы я мог ссылаться на A в общем виде.

)

public abstract class A implements Parcelable { 

    final String globalVar; 

    public A(String globalVar) { 
     this.globalVar = globalVar; 
    } 
} 

Б)

public class B extends A { 

    String bVar; 


    public B(String global, String bVar) { 
     super(global); 
     this.bVar = bVar; 
    } 

    private B(Parcel in) { 
     super(in.readString()); 
     this.bVar = in.readString(); 
    } 


    @Override 
    public int describeContents() { 
     return 0; 
    } 

    @Override 
    public void writeToParcel(Parcel parcel, int i) { 
     parcel.writeString(bVar); 
    } 
} 

С)

public class C extends A { 

    String cVar; 


    public C(String global, String cVar) { 
     super(global); 
     this.cVar = cVar; 
    } 

    @Override 
    public int describeContents() { 
     return 0; 
    } 

    @Override 
    public void writeToParcel(Parcel parcel, int i) { 
     parcel.writeString(cVar); 
    } 
} 
+0

который является абстрактным – Blackbelt

+0

A. Отредактированный ответ. –

+0

, но тогда у вас не может быть создателя в A, потому что он не может быть создан, было бы проще, если бы вы разместили хотя бы часть A – Blackbelt

ответ

-2
public class A implements Parcelable{ 

     public A(){ 

     } 

     public A(Parcel in){ 
      super(in); 
      // read from parcel 
      // number = in.readInt() etc 
     } 

     @Оverride 
     public int describeContents(){ 
      return 0; 
     } 

     @Override 
     public void writeToParcel(Parcel dest, int flags) { 
      super.writeToParcel(out, flags); 
      // write to parcel 
      // out.writeInt 
     } 
     public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 
      public Student createFromParcel(Parcel in) { 
       return new A(in); 
      } 

      public A[] newArray(int size) { 
       return new A[size]; 
      } 
     }; 
    } 

B и C также должны реализовать Parcelable

+0

И как данные B и C Тогда написано? Это было бы мертвым Исправлено, ничего не делая, или я что-то упускаю? –

+0

'super.writeToParcel (out, flags)'; и 'super (in)' в B и C будут следить за чтением данных из A. B и C также необходимо реализовать Parcelable – user840754

+0

Но в проблемной части, когда вы не знаете тип. Как я могу это сделать? Если я позвоню СОЗДАТЕЛЮ вашего класса, B и C не будут затронуты, не так ли? –

11

Я использовал parcelable архитектуру Vincent Mimoun-Прат от этого поста: Parcelable and inheritance in Android и столкнулся с той же проблемой списка типизированных о том, чтобы указать невозможно абстрактную CREATOR.

Поиск в JavaDoc ПАРЦЕЛЛЫ я обнаружил метод writeList(List val), что внутренне использует writeValue(Object) метод для каждого объекта из списка и, следовательно, вызывая writeToParcel() из подклассов (В и С из списка). Чтобы размонтировать список, используйте его аналог readList (List outVal, ClassLoader loader), где должен быть отправлен A ClassLoader или, по крайней мере, в моем случае выброшен android.os.BadParcelableException.

Класс, содержащий список элементов должен быть чем-то вроде этого:

public class AContainer implements Parcelable { 
    //Other AContainer fields 
    List<A> elements = new ArrayList<>(); 
    //Other AContainer fields 

    static final Parcelable.Creator<AContainer> CREATOR = new Parcelable.Creator<AContainer>() { 
     @Override 
     public AContainer createFromParcel(Parcel source) { 
      return new AContainer(source); 
     } 

     @Override 
     public AContainer[] newArray(int size) { 
      return new AContainer[size]; 
     } 
    }; 

    public AContainer() { 
    } 

    protected AContainer(Parcel source) { 
     //read other AContainer fields 
     source.readList(elements, A.class.getClassLoader()); 
     //read other AContainer fields 
    } 

    @Override 
    public int describeContents() { 
     return 0; 
    } 

    @Override 
    public void writeToParcel(Parcel dest, int flags) { 
     //write other AContainer fields 
     dest.writeList(elements); 
     //write other AContainer fields 
    } 
} 

Использование этих методов может быть немного медленнее, чем readTypedList() и writeTypedList() но конкретных данных В и С подклассов также «парцельных», а не только поля из абстрактного суперкласса (невозможно быть абстрактным). Вы восстанавливаете правильные экземпляры из B и C.

+0

Life экономия ответа. Сначала я не мог найти, почему он рушился при разборке, тогда я не знал, как это исправить. К счастью, ваш пост сделал мою 2-часовую депрессию в итоге с улыбкой. Благодаря! – Sufian

+0

Важно отметить, что 'элементы' должны быть инициализированы до вызова метода« Parcel.readList() ». – Henry