Как создать класс с вложенными объектами Parcelable
Я хочу сделать класс A Parcelable.
public class A {
public String str;
public ArrayList<B> list;
}
Это то, что я придумал до сих пор. Однако он выходит из строя с помощью исключения NullPointerException. Проблема состоит в следующем: dest.writeList(list);
и in.readList(list, this.getClass().getClassLoader());
.
Я не могу понять, что делать дальше: (
Класс A
public class A implements Parcelable {
public String str;
public ArrayList<B> list;
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(str);
dest.writeList(list);
}
private A(Parcel in) {
str = in.readString();
in.readList(list, this.getClass().getClassLoader());
}
public static final Parcelable.Creator<A> CREATOR
= new Parcelable.Creator<A>() {
public A createFromParcel(Parcel in) {
return new A(in);
}
public A[] newArray(int size) {
return new A[size];
}
};
}
Класс B
public class B implements Parcelable {
public String str;
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(str);
}
private B(Parcel in) {
str = in.readString();
}
public static final Parcelable.Creator<B> CREATOR
= new Parcelable.Creator<B>() {
public B createFromParcel(Parcel in) {
return new B(in);
}
public B[] newArray(int size) {
return new B[size];
}
};
}
Спасибо за ваше время.
Ответы
Ответ 1
Наконец-то я понял, что набрать в Google:) и нашел это Android, как правильно использовать метод readTypedList в классе Parcelable?
Решение заключалось в том, чтобы вместо этого использовать read-/writeTypedList
. Я также инициализирую arraylist, чтобы избежать дальнейшего исключения NullPointerException.
Класс A
public class A implements Parcelable {
public String str;
public ArrayList<B> list = new ArrayList<B>();
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(str);
dest.writeTypedList(list);
}
private A(Parcel in) {
str = in.readString();
in.readTypedList(list, B.CREATOR);
}
public static final Parcelable.Creator<A> CREATOR
= new Parcelable.Creator<A>() {
public A createFromParcel(Parcel in) {
return new A(in);
}
public A[] newArray(int size) {
return new A[size];
}
};
}
Класс B
public class B implements Parcelable {
public String str;
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(str);
}
private B(Parcel in) {
str = in.readString();
}
public static final Parcelable.Creator<B> CREATOR
= new Parcelable.Creator<B>() {
public B createFromParcel(Parcel in) {
return new B(in);
}
public B[] newArray(int size) {
return new B[size];
}
};
}
Ответ 2
Если у вас есть только один Parcelable
объект внутри основного объекта Parcelable
, не указывайте, как принятый ответ. Тогда это будет выглядеть следующим образом:
Класс A
public class A implements Parcelable {
public String str;
public B objectB;
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
//The parcelable object has to be the first one
dest.writeParcelable(objectB, flags);
dest.writeString(str);
}
private A(Parcel in) {
this.objectB = in.readParcelable(B.class.getClassLoader());
str = in.readString();
}
public static final Parcelable.Creator<A> CREATOR
= new Parcelable.Creator<A>() {
public A createFromParcel(Parcel in) {
return new A(in);
}
public A[] newArray(int size) {
return new A[size];
}
};
}
Класс B
public class B implements Parcelable {
public String str;
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(str);
}
private B(Parcel in) {
str = in.readString();
}
public static final Parcelable.Creator<B> CREATOR
= new Parcelable.Creator<B>() {
public B createFromParcel(Parcel in) {
return new B(in);
}
public B[] newArray(int size) {
return new B[size];
}
};
}
ВАЖНО:
Обратите внимание, что порядок, который вы пишете и читаете объект Parcelable
, имеет значение. Оформить заказ для получения более подробной информации
Ответ 3
При написании посылки
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(name); //if String
parcel.writeTypedList(assignedEmployees); //if List with custom class, eg. List<AssignedEmployee> assignedEmployees
parcel.writeParcelable(checkin,i); //if custom class, eg. Checkin checkin;
}
В конструкторе для чтения обратно
protected A(Parcel in) {
name = in.readString();
assignedEmployees = in.createTypedArrayList(AssignedEmployee.CREATOR);
checkin = in.readParcelable(Checkin.class.getClassLoader());
}
где AssignedEmployee, Checkin, где пользовательские классы и он должен реализовывать Parcelable.
Ответ 4
Просто нажмите ALT + ENTER и замените Parcelable, он реализует всю необходимую реализацию
Ответ 5
Вы можете добавить плагин генератора кода Parcelable из prefs, оттуда вы можете создать код сборной котельной, выполнив:
- имя класса правой кнопки мыши в модели
- выберите сгенерировать
- выберите Parcelable
presto - ваша модель будет обновлена с помощью необходимого Пакетного шаблона.
Ответ 6
У меня была такая же проблема здесь общая версия
class Item<T : Parcelable> (val model: T, val index: Int ) : Parcelable {
constructor(parcel: Parcel) :
this(parcel.readParcelable(
Item<T>::model.javaClass.classLoader),
parcel.readInt()
) {}
override fun writeToParcel(parcel: Parcel?, flag: Int) {
parcel?.writeParcelable(model, 0)
parcel?.writeInt(index)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<Item<Parcelable>> {
override fun createFromParcel(parcel: Parcel): Item<Parcelable> {
return Item(parcel)
}
override fun newArray(size: Int): Array<Item<Parcelable>?> {
return arrayOfNulls(size)
}
}
}
Ответ 7
К сожалению, я использовал класс (BarEntry
) из сторонней библиотеки, который не мог быть разделен. Я решил свою проблему, пройдя через Intent
массив с float
и затем восстановив мои объекты BarEntry
на принимающей стороне.
Это неоптимально, но это может быть полезным процессом, если у кого-то есть аналогичные обстоятельства, когда создание объекта посылки невозможно.