Android中Parcelable接口用法
from:
http://www.cnblogs.com/renqingping/archive/2012/10/25/Parcelable.html
Interface for classes whose instances can be written to and restored from a Parcel。 Classes implementing the Parcelable interface must also have a static field called CREATOR, which is an object implementing the Parcelable.Creator interface。
1 public interface Parcelable { 2 public static final int PARCELABLE_WRITE_RETURN_VALUE = 0x0001; 3 public static final int CONTENTS_FILE_DESCRIPTOR = 0x0001; 4 public int describeContents();//返回0即可
//一个是把本对象(实现了Parcelable的对象)的数据写入Parcel中 5 public void writeToParcel(Parcel dest, int flags); 6 /** 7 * Interface that must be implemented and provided as a public CREATOR 8 * field that generates instances of your Parcelable class from a Parcel. 9 */ 10 public interface Creator<T> {//提供一个内部类,供反序列化的时候把Parcel对象转化为对象,即本对象 11 /** 12 * Create a new instance of the Parcelable class, instantiating it 13 * from the given Parcel whose data had previously been written by 14 * {@link Parcelable#writeToParcel Parcelable.writeToParcel()}. 15 * 16 * @param source The Parcel to read the object's data from. 17 * @return Returns a new instance of the Parcelable class. 18 */ 19 public T createFromParcel(Parcel source);//读出source中的数据给T(即本对象) 20 21 /** 22 * Create a new array of the Parcelable class. 23 * 24 * @param size Size of the array. 25 * @return Returns an array of the Parcelable class, with every entry 26 * initialized to null. 27 */ 28 public T[] newArray(int size); 29 } 30 public interface ClassLoaderCreator<T> extends Creator<T> { 31 public T createFromParcel(Parcel source, ClassLoader loader); 32 } 33 }
2.序列化的原因
1)永久性保存对象,保存对象的字节序列到本地文件中;
2)通过序列化对象在网络中传递对象;
3)通过序列化在进程间传递对象。
3.Parcelable与Serializable的对比
-
Parcelable
1.android特有;
2.实现复杂;
3.比Serializable高效
4.可以用于进程间通信(IPC),也可用于intent通讯;
5.不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。
6.复杂类型必须实现Parcelable接口。
-
Serializable
1.java SE实现;
2.在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3.实现简单
Parcel是公共的内存空间,所以可以存、取数据。由于是内存操作,所以要比Serialize利用外部存储设备来存、取数据要快!
如果要发送对象最简单的方法是: 把要发的数据直接当做对象发送,接收也不用Bundle(这是可以的),因为已经默认创建。
4.public static final一个都不能少,内部对象CREATOR的名称也不能改变,必须全部大写。
简而言之:通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射成你的对象。
5.简单例子
1 public class Person implements Parcelable { 2 private String name; 3 private int age; 4 private static final String TAG = "Person"; 5 6 public String getName() { 7 return name; 8 } 9 10 public void setName(final String name) { 11 this.name = name; 12 } 13 14 public int getAge() { 15 return age; 16 } 17 18 public void setAge(final int age) { 19 this.age = age; 20 } 21 22 public static final Parcelable.Creator<Person> CREATOR = new Creator<Person>() { 23 @Override 24 public Person createFromParcel(final Parcel source) { 25 Log.d(TAG, "createFromParcel"); 26 Person mPerson = new Person(); 27 mPerson.name = source.readString(); 28 mPerson.age = source.readInt(); 29 return mPerson; 30 } 31 32 @Override 33 public Person[] newArray(final int size) { 34 // TODO Auto-generated method stub 35 return new Person[size]; 36 } 37 }; 38 39 @Override 40 public int describeContents() { 41 // TODO Auto-generated method stub 42 Log.d(TAG, "describeContents"); 43 return 0; 44 } 45 46 @Override 47 public void writeToParcel(final Parcel dest, final int flags) { 48 // TODO Auto-generated method stub 49 Log.d(TAG, "writeToParcel"); 50 dest.writeString(name); 51 dest.writeInt(age); 52 } 53 }
6.writeToParcel()写和createFromParcel()读对象的数据们的顺序必须一致;