今天和同学交流传递集合数据时候,我直接建议同学使用putSerializable传递一个序列化对象,然后获取到该对象中list集合拿来使用,但是同学说她们不这样用使用putParcelableArrayListExtra直接传递一个集合,我就有点好奇这两者有什么不同,我当初为什么使用第一种方法,就去网上查了资料,大彻大悟。
1)writeToParcel 方法。该方法将类的数据写入外部提供的Parcel中.声明如下:
writeToParcel (Parcel dest, int flags) 具体参数含义见javadoc
2)describeContents方法。没搞懂有什么用,反正直接返回0也可以
3)静态的Parcelable.Creator接口,本接口有两个方法:
createFromParcel(Parcel in) 实现从in中创建出类的实例的功能
newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话(return new T[size])即可。估计本方法是供外部类反序列化本类数组使用。
一 序列化原因:
1.永久性保存对象,保存对象的字节序列到本地文件中;
2.通过序列化对象在网络中传递对象;
3.通过序列化在进程间传递对象。
二 至于选取哪种可参考下面的原则:
1.在使用内存的时候,Parcelable 类比Serializable性能高,所以推荐使用Parcelable类。
2.Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3.Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点, 也不提倡用,但在这种情况下,还是建议你用Serializable 。
看到上面解释后,我才知道自己犯了多大错误。同样也抱着对Parcelable的好感和好奇心去做了一个Demo进行测试。在测试过程中也碰到了一些问题总结如下:
1、仅仅传递一个自定义对象,自定义对象中都是基本数据类型(集合类型也是基本数据类型),直接实现Parcelable接口,按照提示实现其中方法,通过putExtra传递即可。
2、传递的自定义对象中含有集合(此处的自定义对象实现了Parcelable接口),集合中的数据也是自定义对象类型(集合必须是ArrayList,否则会报错),此时需要注意以下两点:
(1)对于没有经验的我,集合中的自定义对象就直接定义一个bean(没有实现Parcelable接口和Serialization接口),传递数据时候直接报错:Parcel: unable to marshal value
(2)针对上面的问题,百度才知道集合中的数据类型要实现Serialization接口或者Parcelable接口,实现Parcelable接口时候,注意集合要用ArrayList定义,最开始我在protected构造方法中使用的是ClassLoader.getSystemClassLoader(),运行报错:android.os.BadParcelableException: ClassNotFoundException when unmarshal 修改为Books.class.getClassLoader()即可
第一次使用Parcelable传递自定义对象真是呕心沥血,现附上代码,以供参考。
3、直接传递集合,集合中的bean实现Parcelable接口,使用putParcelableArrayListExtra传递数据,注意:要使用ArrayList定义集合。
Students.java:
public class Students implements Parcelable { public ArrayList<Books> list; public Students(ArrayList<Books> list){ this.list = list; } protected Students(Parcel in) { list = in.readArrayList(Books.class.getClassLoader()); } public static final Creator<Students> CREATOR = new Creator<Students>() { @Override public Students createFromParcel(Parcel in) { return new Students(in); } @Override public Students[] newArray(int size) { return new Students[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int i) { parcel.writeList(list); } }Books.java:
public class Books implements Parcelable{ public String name; public int price; public Books(String name,int price){ this.name = name; this.price = price; } protected Books(Parcel in) { name = in.readString(); price = in.readInt(); } public static final Creator<Books> CREATOR = new Creator<Books>() { @Override public Books createFromParcel(Parcel in) { return new Books(in); } @Override public Books[] newArray(int size) { return new Books[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int i) { parcel.writeString(name); parcel.writeInt(price); } }