我有这门课:

public class Foo implements Parcelable {
    private int id;
    private MyFoo myFoo
    private ForeignCollection<MyFoo2> myFoo2s;

    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(id);
        out.writeParcel(myFoo, flags);
        out.write //How can I write the ForeignCollection?
    }

    public Foo(Parcel in) {
        id = in.readInt();
        myFoo = in.readParcelable(getClass().getClassLoader())
        myFoo2s = // How can I read the ForeignCollection?
    }

    public static final Parcelable.Creator<Foo> CREATOR = new Parcelable.Creator<Foo>() {
        public Foo createFromParcel(Parcel in) {
            return new Foo(in);
        }

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

myfoo和myfoo2类也实现了parcelable,但foreigncollection没有做到这一点。ForeignCollection是一个实现接口的类:collection、closeableiterable和iterable。
我不能使用out.writeList,因为foreigncollection没有实现list接口。

最佳答案

看起来不可能把这个集合放到Parcel。但是,您仍然可以使用来自this answer的基于正常序列化的输入。
代码可能如下所示(代码采用上述链接):

public static class SerializationUtility {
    /** Read the object from Base64 string. */
    static Object fromString(String s) throws IOException ,
            ClassNotFoundException {
        final byte [] data = Base64.decode(s, Base64.DEFAULT);
        final ObjectInputStream ois = new ObjectInputStream(
                new ByteArrayInputStream(data));
        final Object o  = ois.readObject();

        ois.close();

        return o;
    }

    /** Write the object to a Base64 string. */
    static  String toString(Serializable o) throws IOException {
        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        final ObjectOutputStream oos = new ObjectOutputStream(baos);

        oos.writeObject(o);
        oos.close();
        return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
    }
}

public static class Foo implements Parcelable {
    private int id;
    private MyFoo myFoo;
    private ForeignCollection<MyFoo2> myFoo2s;

    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(id);
        out.writeParcelable(myFoo, flags);

        // Actually, this should be always true
        if (myFoo2s instanceof Serializable) {
            try {
                out.writeString(SerializationUtility.toString((Serializable) myFoo2s));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @SuppressWarnings("unchecked")
    public Foo(Parcel in) {
        id = in.readInt();
        myFoo = in.readParcelable(getClass().getClassLoader());
        try {
            myFoo2s = (ForeignCollection<MyFoo2>) SerializationUtility.fromString(in.readString());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static final Parcelable.Creator<Foo> CREATOR = new Parcelable.Creator<Foo>() {
        public Foo createFromParcel(Parcel in) {
            return new Foo(in);
        }

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

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

是的,它有一些缺点(如未经检查的警告),其速度将低于正常值Parcelable,但仍应高于正常值Seriazable,特别是当MyFoo相当复杂/很大时。

08-04 08:43