简体   繁体   中英

How to make generic arraylist parcelable in Android?

I have such a Class: (full definition can be found here )

public class AList<T> {
    private ArrayList<T> list = new ArrayList<>();
}

It is a C#-like generic list.

How should I implement AList as a Parcelable ? I have found examples online but their data types are determined. How should I deal with generic types?

This is my current try:

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

but the constructor would give me BadParcelableException .

I have also tried this:

protected AList(Parcel in) {
    in.readList(list, T.class.getClassLoader());
}

but T cannot be used as a variable so I don't know how to fix this syntax.

In order for your List to be parcelable, each element of that List should implement Parcelable . So basically you would define your List as ArrayList<Parcelable> list = new ArrayList<>()

SomeClass implements Parcelable {
...
}

A couple of tests:

list.add("test"); // error, String doesn't implement Parcelable
list.add(new SomeClass()); // fine
list.add(new android.location.Address(Locale.getDefault())); // fine

This is commonly used to attach data to Intent s, example:

Intent i = new Intent(this, SomeActivity.class)
i.putParcelableArrayListExtra("key", list);

I have given up implementing AList as a Parcelable . However, since AList is ArrayList -like, I can treat it exactly as an ArrayList when I need to write AList<T> to Parcel.

For example, I have a AList<Tag> Tags declared in Food class. So in protected Food(Parcel in) , I can write:

    ArrayList<Tag> tags = new ArrayList<>();
    in.readTypedList(tags, Tag.CREATOR);
    Tags = new AList<>(tags);

Of course, I have implemented Tag as a Parcelable . And I can have such 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);
    }
}

My source code for Food class is 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];
    }
};

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM