Domanda

I have this class:

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 and MyFoo2 classes implements Parcelable too, but ForeignCollection doesn't do it. ForeignCollection is a class that implements the interfaces: Collection, CloseableIterable and Iterable.

I cannot use out.writeList because ForeignCollection doesn't implement List interface.

È stato utile?

Soluzione

Looks like it's impossible to put that collection to Parcel. However, You can still use input from this answer based on normal Serialization.

The code could look like the following (code is adopted from above link):

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();
    }
}

Yes, it has some downsides (like unchecked warning) and speed of it will be slower than normal Parcelable, however it should be still faster than normal Seriazable especially if MyFoo is quite complex / big.

Altri suggerimenti

here you can find an example that shows a solution to your problem:

  • Gift is the object I'm making Parcelable.
  • image: consider it as the only variable in this class and that it is a collection of Integer
  • method getImage: returns a collection of Integer (Collection)

You can apply this pattern to your objects that implement 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. do not use Collection.sort(imageList) in the writeToParcel method, because I would change the order of your collection reordering the elements in an ascending order.

Bests

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top