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];
}
};
}