今天和同学交流传递集合数据时候,我直接建议同学使用putSerializable传递一个序列化对象,然后获取到该对象中list集合拿来使用,但是同学说她们不这样用使用putParcelableArrayListExtra直接传递一个集合,我就有点好奇这两者有什么不同,我当初为什么使用第一种方法,就去网上查了资料,大彻大悟。
自定义对象的传递:
通过intent 传递自定义对象的方法有两个,第一是实现Serialization接口,第二是实现Parcelable接口。
首选推荐Parceable,android中的很多数据类型都是实现Serialable接口方式来传递的,例如 Intent、Bundle、Bitmap、Uri等等。
android Parcelable化的提供了一个接口 Parcelable和一个工具类 Parcel
Parcelable:一个规范接口,定义实现Parcelable需要实现的功能
Parcel:数据存取的工具类,供用户在实现Parcelable接口时存取自定义数据用,也供系统传递数据时使用。
Parcelable实现要点:需要实现三个东西
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,否则会报错),此时需要注意以下两点:
Parcelable接口和Serialization接口),传递数据时候直接报错:Parcel: unable to marshal value
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);
}
}