如何在 Android 中使通用数组列表可打包?
How to make generic arraylist parcelable in Android?
我有这样一个Class:(可以找到完整的定义here)
public class AList<T> {
private ArrayList<T> list = new ArrayList<>();
}
这是一个类似于 C# 的泛型列表。
我应该如何将 AList
实现为 Parcelable
?我在网上找到了例子,但它们的数据类型是确定的。我应该如何处理泛型类型?
这是我目前的尝试:
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeList(list);
}
protected AList(Parcel in) {
list = in.readArrayList(null);
}
public static final Creator<AList> CREATOR = new Creator<AList>() {
@Override
public AList createFromParcel(Parcel in) {
return new AList(in);
}
@Override
public AList[] newArray(int size) {
return new AList[size];
}
};
但构造函数会给我 BadParcelableException
。
我也试过这个:
protected AList(Parcel in) {
in.readList(list, T.class.getClassLoader());
}
但是 T
不能用作变量,所以我不知道如何修正这个语法。
为了使您的 List
可打包,List
的每个元素都应实现 Parcelable
。所以基本上你会定义你的 List 为 ArrayList<Parcelable> list = new ArrayList<>()
SomeClass implements Parcelable {
...
}
一些测试:
list.add("test"); // error, String doesn't implement Parcelable
list.add(new SomeClass()); // fine
list.add(new android.location.Address(Locale.getDefault())); // fine
这通常用于将数据附加到Intent
s,例如:
Intent i = new Intent(this, SomeActivity.class)
i.putParcelableArrayListExtra("key", list);
我已经放弃将 AList
实现为 Parcelable
。但是,由于 AList
类似于 ArrayList
,所以当我需要将 AList<T>
写入 Parcel.
时,我可以将其完全视为 ArrayList
例如,我在 Food
class 中声明了一个 AList<Tag> Tags
。所以在protected Food(Parcel in)
中,我可以写:
ArrayList<Tag> tags = new ArrayList<>();
in.readTypedList(tags, Tag.CREATOR);
Tags = new AList<>(tags);
当然,我已经将Tag
实现为Parcelable
。而我可以拥有这样的 writeToParcel
:
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(Name);
dest.writeString(ImagePath);
dest.writeTypedList(Tags.ToArrayList());
dest.writeString(Note);
dest.writeByte((byte) (IsFavorite ? 1 : 0));
if (DateAdded == null) {
dest.writeByte((byte) 0);
} else {
dest.writeByte((byte) 1);
dest.writeLong(DateAdded);
}
}
我的 Food
class 的源代码是 here。
public class Sample<T> implements Parcelable {
ArrayList<T> list;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeList(this.list);
}
public Sample() {
}
protected Sample(Parcel in) {
this.list = new ArrayList<T>();
in.readList(this.list, T.class.getClassLoader());
}
public static final Parcelable.Creator<Sample> CREATOR = new Parcelable.Creator<Sample>() {
@Override
public Sample createFromParcel(Parcel source) {
return new Sample(source);
}
@Override
public Sample[] newArray(int size) {
return new Sample[size];
}
};
}
我有这样一个Class:(可以找到完整的定义here)
public class AList<T> {
private ArrayList<T> list = new ArrayList<>();
}
这是一个类似于 C# 的泛型列表。
我应该如何将 AList
实现为 Parcelable
?我在网上找到了例子,但它们的数据类型是确定的。我应该如何处理泛型类型?
这是我目前的尝试:
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeList(list);
}
protected AList(Parcel in) {
list = in.readArrayList(null);
}
public static final Creator<AList> CREATOR = new Creator<AList>() {
@Override
public AList createFromParcel(Parcel in) {
return new AList(in);
}
@Override
public AList[] newArray(int size) {
return new AList[size];
}
};
但构造函数会给我 BadParcelableException
。
我也试过这个:
protected AList(Parcel in) {
in.readList(list, T.class.getClassLoader());
}
但是 T
不能用作变量,所以我不知道如何修正这个语法。
为了使您的 List
可打包,List
的每个元素都应实现 Parcelable
。所以基本上你会定义你的 List 为 ArrayList<Parcelable> list = new ArrayList<>()
SomeClass implements Parcelable {
...
}
一些测试:
list.add("test"); // error, String doesn't implement Parcelable
list.add(new SomeClass()); // fine
list.add(new android.location.Address(Locale.getDefault())); // fine
这通常用于将数据附加到Intent
s,例如:
Intent i = new Intent(this, SomeActivity.class)
i.putParcelableArrayListExtra("key", list);
我已经放弃将 AList
实现为 Parcelable
。但是,由于 AList
类似于 ArrayList
,所以当我需要将 AList<T>
写入 Parcel.
ArrayList
例如,我在 Food
class 中声明了一个 AList<Tag> Tags
。所以在protected Food(Parcel in)
中,我可以写:
ArrayList<Tag> tags = new ArrayList<>();
in.readTypedList(tags, Tag.CREATOR);
Tags = new AList<>(tags);
当然,我已经将Tag
实现为Parcelable
。而我可以拥有这样的 writeToParcel
:
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(Name);
dest.writeString(ImagePath);
dest.writeTypedList(Tags.ToArrayList());
dest.writeString(Note);
dest.writeByte((byte) (IsFavorite ? 1 : 0));
if (DateAdded == null) {
dest.writeByte((byte) 0);
} else {
dest.writeByte((byte) 1);
dest.writeLong(DateAdded);
}
}
我的 Food
class 的源代码是 here。
public class Sample<T> implements Parcelable {
ArrayList<T> list;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeList(this.list);
}
public Sample() {
}
protected Sample(Parcel in) {
this.list = new ArrayList<T>();
in.readList(this.list, T.class.getClassLoader());
}
public static final Parcelable.Creator<Sample> CREATOR = new Parcelable.Creator<Sample>() {
@Override
public Sample createFromParcel(Parcel source) {
return new Sample(source);
}
@Override
public Sample[] newArray(int size) {
return new Sample[size];
}
};
}