包含包含具有自定义对象的集合的模型

时间:2013-09-18 08:40:05

标签: android ormlite parcelable parcel

我有这堂课:

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接口。

2 个答案:

答案 0 :(得分:2)

看起来无法将该集合放到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是{{1}}相当复杂/大。

答案 1 :(得分:1)

在这里,您可以找到一个显示问题解决方案的示例:

  • 礼物是我制作Parcelable的对象。
  • image:将其视为此类中唯一的变量,并且它是Integer的集合
  • 方法getImage:返回Integer(Collection)
  • 的集合

您可以将此模式应用于实现Collection

的对象
public void writeToParcel(Parcel parcel, int i) {

        List imageList = new ArrayList(getImage());
        parcel.writeList(imageList);
}

public Gift(Parcel source){

        image = source.readArrayList(Integer.class.getClassLoader());

}

P.S。不要在writeToParcel方法中使用Collection.sort(imageList),因为我会按升序重新排序元素的顺序。

贝斯茨