android开发过程中需要对一些对象进行传递,但是要对数据进行传递需要对所传对象进行序列化,而java也提供了相应的类来处理,下面对Parcelable和Serializable做一下简单的介绍。
Parcelable的性能比Serializable好,在内存开销方面较小,所以在内存间数据传输时推荐使用Parcelable,如activity间传输数据,而Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable,因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化
//对数组对象的读出
Parcelable[] pars = in.readParcelableArray(Test1.class.getClassLoader());
test1s = Arrays.asList(Arrays.asList(pars).toArray(new Test1[pars.length]));
parcel.writeString(name);
parcel.writeParcelable(test1, i);
parcel.writeParcelableArray(test1s.toArray(new Test1[test1s.size()]), i);
针对网上有很多人在对对象序列化时test1 = in.readParcelable(null);也可能出现这样的错误,所以原理理解好是快速编码的关键,然后就是认证的编码然后序列化的顺序要一致。
1、Parcelable和Serializable都是java中对数据进行序列化的
Serializable的作用是为了保存对象的属性到本地文件、数据库、网络流、rmi以方便数据传输,当然这种传输可以是程序内的也可以是两个程序间的。而Android的Parcelable的设计初衷是因为Serializable效率过慢,为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在,Parcelable是通过IBinder通信的消息的载体Parcelable的性能比Serializable好,在内存开销方面较小,所以在内存间数据传输时推荐使用Parcelable,如activity间传输数据,而Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable,因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化
2、下面介绍一下不同情况下的实现以及容易出现的问题
public class Test implements Parcelable {
String name;
Test1 test1;
List<Test1> test1s;
/**
* 将数据读出,要求写入的数据和读出的数据保持一致,不然会出项一些你意想不到的问题
* 然后就是针对对象的读出
*
* @param in
*/
protected Test(Parcel in) {
name = in.readString();
test1 = in.readParcelable(Test1.class.getClassLoader());//对对象的读出
//对数组对象的读出
Parcelable[] pars = in.readParcelableArray(Test1.class.getClassLoader());
test1s = Arrays.asList(Arrays.asList(pars).toArray(new Test1[pars.length]));
}
public static final Creator<Test> CREATOR = new Creator<Test>() {
@Override
public Test createFromParcel(Parcel in) {
return new Test(in);
}
@Override
public Test[] newArray(int size) {
return new Test[size];
}
};
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Test1 getTest1() {
return test1;
}
public void setTest1(Test1 test1) {
this.test1 = test1;
}
public List<Test1> getTest1s() {
return test1s;
}
public void setTest1s(List<Test1> test1s) {
this.test1s = test1s;
}
@Override
public int describeContents() {
return 0;
}
/**
* 将数据读出,要求写入的数据和读出的数据保持一致,不然会出项一些你意想不到的问题
* 然后就是针对对象的读出
*/
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(name);
parcel.writeParcelable(test1, i);
parcel.writeParcelableArray(test1s.toArray(new Test1[test1s.size()]), i);
}
}
3、对对象序列化的和对数组对象的序列化
test1 = in.readParcelable(Test1.class.getClassLoader());//对对象的读出//对数组对象的读出
Parcelable[] pars = in.readParcelableArray(Test1.class.getClassLoader());
test1s = Arrays.asList(Arrays.asList(pars).toArray(new Test1[pars.length]));
parcel.writeString(name);
parcel.writeParcelable(test1, i);
parcel.writeParcelableArray(test1s.toArray(new Test1[test1s.size()]), i);
4、对象序列化的和对数组对象的序列化错误往往会出现以下的错误:
android.os.BadParcelableException: ClassNotFoundException when unmarshalling:解决办法针对网上有很多人在对对象序列化时test1 = in.readParcelable(null);也可能出现这样的错误,所以原理理解好是快速编码的关键,然后就是认证的编码然后序列化的顺序要一致。