android中Parcelable接口的使用
一、理解
Parcelable是一個接口、用來實現序列化。與此類似的還有一個接口Serializable,這是JavaSE本身支持的,而Parcelable是android特有的。二者比較:
1、Parcelable使用起來稍復雜點,而后者使用起來非常簡單。下面例子中會看到。
2、Parcelable效率比Serializable高,支持Intent數據傳遞,也支持進程間通信(IPC)。
3、Parcelable使用時要用到一個Parcel,可以簡單將其看為一個容器,序列化時將數據寫入Parcel,反序列化時從中取出。
4、在使用內存的時候,Parcelable比Serializable性能高,所以推薦使用Parcelable。Serializable在序列化的時候會產生大量的臨時變量,從而引起頻繁的GC。Parcelable不能使用在要將數據存儲在磁盤上的情況,因為Parcelable在外界有變化的情況下不能很好的保證數據的持續性。盡管Serializable效率低點,但此時還是建議使用Serializable 。
二、源碼
結合源碼及注釋進行理解:
- package android.os;
- /**
- * Interface for classes whose instances can be written to
- * and restored from a {@link Parcel}. Classes implementing the Parcelable
- * interface must also have a static field called <code>CREATOR</code>, which
- * is an object implementing the {@link Parcelable.Creator Parcelable.Creator}
- * interface.
- *
- * <p>A typical implementation of Parcelable is:</p>
- *
- * <pre>
- * public class MyParcelable implements Parcelable {
- * private int mData;
- *
- * public int describeContents() {
- * return 0;
- * }
- *
- * public void writeToParcel(Parcel out, int flags) {
- * out.writeInt(mData);
- * }
- *
- * public static final Parcelable.Creator<MyParcelable> CREATOR
- * = new Parcelable.Creator<MyParcelable>() {
- * public MyParcelable createFromParcel(Parcel in) {
- * return new MyParcelable(in);
- * }
- *
- * public MyParcelable[] newArray(int size) {
- * return new MyParcelable[size];
- * }
- * };
- *
- * private MyParcelable(Parcel in) {
- * mData = in.readInt();
- * }
- * }</pre>
- */
- public interface Parcelable {
- /**
- * Flag for use with {@link #writeToParcel}: the object being written
- * is a return value, that is the result of a function such as
- * "<code>Parcelable someFunction()</code>",
- * "<code>void someFunction(out Parcelable)</code>", or
- * "<code>void someFunction(inout Parcelable)</code>". Some implementations
- * may want to release resources at this point.
- */
- public static final int PARCELABLE_WRITE_RETURN_VALUE = 0x0001;
- /**
- * Bit masks for use with {@link #describeContents}: each bit represents a
- * kind of object considered to have potential special significance when
- * marshalled.
- */
- public static final int CONTENTS_FILE_DESCRIPTOR = 0x0001;
- /**
- * Describe the kinds of special objects contained in this Parcelable's
- * marshalled representation.
- *
- * @return a bitmask indicating the set of special object types marshalled
- * by the Parcelable.
- */
- public int describeContents();
- /**
- * Flatten this object in to a Parcel.
- *
- * @param dest The Parcel in which the object should be written.
- * @param flags Additional flags about how the object should be written.
- * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
- */
- public void writeToParcel(Parcel dest, int flags);
- /**
- * Interface that must be implemented and provided as a public CREATOR
- * field that generates instances of your Parcelable class from a Parcel.
- */
- public interface Creator<T> {
- /**
- * Create a new instance of the Parcelable class, instantiating it
- * from the given Parcel whose data had previously been written by
- * {@link Parcelable#writeToParcel Parcelable.writeToParcel()}.
- *
- * @param source The Parcel to read the object's data from.
- * @return Returns a new instance of the Parcelable class.
- */
- public T createFromParcel(Parcel source);
- /**
- * Create a new array of the Parcelable class.
- *
- * @param size Size of the array.
- * @return Returns an array of the Parcelable class, with every entry
- * initialized to null.
- */
- public T[] newArray(int size);
- }
- /**
- * Specialization of {@link Creator} that allows you to receive the
- * ClassLoader the object is being created in.
- */
- public interface ClassLoaderCreator<T> extends Creator<T> {
- /**
- * Create a new instance of the Parcelable class, instantiating it
- * from the given Parcel whose data had previously been written by
- * {@link Parcelable#writeToParcel Parcelable.writeToParcel()} and
- * using the given ClassLoader.
- *
- * @param source The Parcel to read the object's data from.
- * @param loader The ClassLoader that this object is being created in.
- * @return Returns a new instance of the Parcelable class.
- */
- public T createFromParcel(Parcel source, ClassLoader loader);
- }
- }
三、示例
Student:
- package com.home.testparcelable;
- import android.os.Parcel;
- import android.os.Parcelable;
- public class Student implements Parcelable {
- private int id;
- private String name;
- public Student() {
- super();
- }
- public Student(int id, String name) {
- super();
- this.id = id;
- this.name = name;
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- @Override
- public int describeContents() {
- return 0;
- }
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- // 序列化過程:必須按成員變量聲明的順序進行封裝
- dest.writeInt(id);
- dest.writeString(name);
- }
- // 反序列過程:必須實現Parcelable.Creator接口,並且對象名必須為CREATOR
- // 讀取Parcel里面數據時必須按照成員變量聲明的順序,Parcel數據來源上面writeToParcel方法,讀出來的數據供邏輯層使用
- public static final Parcelable.Creator<Student> CREATOR = new Creator<Student>() {
- @Override
- public Student createFromParcel(Parcel source) {
- return new Student(source.readInt(), source.readString());
- }
- @Override
- public Student[] newArray(int size) {
- return new Student[size];
- }
- };
- }
MainActivity:
- package com.home.testparcelable;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class MainActivity extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- Button btn = (Button) findViewById(R.id.main_btn);
- btn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- Intent in = new Intent(MainActivity.this, SecondActivity.class);
- in.putExtra("stu", new Student(1, "張三"));
- startActivity(in);
- }
- });
- }
- }
SecondActivity:
- package com.home.testparcelable;
- import android.app.Activity;
- import android.os.Bundle;
- public class SecondActivity extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- Student stu = getIntent().getParcelableExtra("stu");
- System.out.println("id:" + stu.getId());
- System.out.println("name:" + stu.getName());
- }
- }
自己實現的:
package com.yangfuhai.asimplecachedemo;
import android.annotation.SuppressLint;
import android.os.Parcel;
import android.os.Parcelable;
/***
* 實現Parcelable接口實例模型
*
* @author Administrator
*
*/
public class Test implements Parcelable {
private int noId;
private String userName;
private String address;
public Test() {
}
@SuppressLint("ParcelCreator")
public Test(int noId, String userName, String address) {
this.noId = noId;
this.userName = userName;
this.address = address;
}
public int getNoId() {
return noId;
}
public void setNoId(int noId) {
this.noId = noId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public static Creator<Test> getCreator() {
return creator;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(noId);
dest.writeString(userName);
dest.writeString(address);
}
public static final Creator<Test> creator = new Creator<Test>() {
@Override
public Test createFromParcel(Parcel source) {
return new Test(source.readInt(), source.readString(),
source.readString());
}
@Override
public Test[] newArray(int size) {
return new Test[size];
}
};
}
public static final Creator<Test> creator=new Creator<Test>() {
@Override
public Test createFromParcel(Parcel source) {
return new Test(source.readInt(),source.readString(),source.readString());
}
@Override
public Test[] newArray(int size) {
return new Test[size];
}
};
}