对象为什么需要序列化
1.永久性保存对象,保存对象的字节序列到本地文件。
2.通过序列化对象在网络中传递对象。
3.通过序列化对象在进程间传递对象。
Android对象序列化:
一、
1、关于java中传统的序列化方式Serializable的内容详见设计模式一文的单例模式的③部分。但是由于Serializable是序列化到文件中
2、Android中提供了一个新的序列化方式:实现Parcelable接口。一般需要以下三个操作
①实现writeToParcel()将对象属性序列化到Parcel中
②实现Parcelable.Creator<Person>类型的接口,并且需要名称为CREATOR。该接口有两个方法:一个返回反序列化的对象(注意读取保存的属性的顺序必须和存储时的一致),一个返回一个该对象数组
③对于describeContents(),一般情况下默认返回0即可
1 public class MyColor implements Parcelable { 2 private int color=Color.BLACK; 3 private int a=1; 4 5 MyColor(){ 6 color=Color.BLACK; 7 } 8 9 MyColor(Parcel in){ 10 color=in.readInt(); 11 a=in.readInt(); 12 } 13 14 public int getColor(){ 15 return color; 16 } 17 18 public void setColor(int color){ 19 this.color=color; 20 } 21 22 @Override 23 public int describeContents() { 24 return 0; 25 } 26 27 @Override 28 public void writeToParcel(Parcel dest, int flags) { 29 dest.writeInt(a); 30 dest.writeInt(color); 31 } 32 33 public static final Parcelable.Creator<MyColor> CREATOR 34 = new Parcelable.Creator<MyColor>() { 35 public MyColor createFromParcel(Parcel in) { 36 MyColor mc=new MyColor(); 37 //注意:这里读取的顺序必须和保存的顺序一致,否则不能正确读取 38 mc.a=in.readInt(); 39 mc.setColor(in.readInt()); 40 return mc; 41 } 42 43 public MyColor[] newArray(int size) { 44 return new MyColor[size]; 45 } 46 }; 47 }
关于如何选择使用序列化方式:
1.在使用内存的时候Parcelable比Serializable的性能高。
2.Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC(内存回收)。
3.Parcelable不能使用在将对象存储在磁盘上这种情况,因为在外界的变化下Parcelable不能很好的保证数据的持续性。
二、在Intent中传递数据可以使用Bundle对象,本质上是一个实现了Parcelable接口的ArrayMap。Bundle传值和Intent传值的区别在于:前者可以在多个activity中进行传递,而Intent只能在两个activity间传递,若要继续传递则需重新封装。
1、Bundle大部分功能都依赖其父类BaseBundle实现
1 //父类中有的方法直接调用 2 @Override 3 public void putShort(@Nullable String key, short value) { 4 super.putShort(key, value); 5 } 6 //父类中没有的方法则直接使用mMap进行存储即可 7 public void putParcelable(@Nullable String key, @Nullable Parcelable value) { 8 unparcel(); 9 mMap.put(key, value); 10 mFdsKnown = false; 11 } 12 13 //mMap是继承自父类的属性,声明如下 14 ArrayMap<String, Object> mMap = null;
2、Bundle中实现序列化的方法:
1 @Override 2 public void writeToParcel(Parcel parcel, int flags) { 3 final boolean oldAllowFds = parcel.pushAllowFds(mAllowFds); 4 try { 5 super.writeToParcelInner(parcel, flags); 6 } finally { 7 parcel.restoreAllowFds(oldAllowFds); 8 } 9 } 10 11 public static final Parcelable.Creator<Bundle> CREATOR = 12 new Parcelable.Creator<Bundle>() { 13 @Override 14 public Bundle createFromParcel(Parcel in) { 15 return in.readBundle(); 16 } 17 18 @Override 19 public Bundle[] newArray(int size) { 20 return new Bundle[size]; 21 } 22 }; 23 24 @Override 25 public int describeContents() { 26 int mask = 0; 27 if (hasFileDescriptors()) { 28 mask |= Parcelable.CONTENTS_FILE_DESCRIPTOR; 29 } 30 return mask; 31 }