如何在 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

这通常用于将数据附加到Intents,例如:

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

}