Android中Intent如果要传递类对象,可以通过两种方式实现。
方式一:Serializable,要传递的类实现Serializable接口传递对象,
方式二:Parcelable,要传递的类实现Parcelable接口传递对象。
Serializable(Java自带):
Serializable是序列化的意思,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。Serializable是一种标记接口,这意味着无需实现方法,Java便会对这个对象进行高效的序列化操作。
Parcelable(Android 专用):
Android的Parcelable的设计初衷是因为Serializable效率过慢(使用反射),为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在。Parcelable方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了。
效率及选择:
Parcelable的性能比Serializable好,因为后者在反射过程频繁GC,所以在内存间数据传输时推荐使用Parcelable,如activity间传输数据。而Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable,因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化。 Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable 。
通过intent传递复杂数据类型时必须先实现两个接口之一,对应方法分别是getSerializableExtra(),getParcelableExtra()。
利用java自带的Serializable 进行序列化:
public class Person implements Serializable{
private static final long serialVersionUID = 7362356359068556080L;
private String name;
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在activity中:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.mTv).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
Person person = new Person();
person.setName("大家好");
person.setAge(20);
// public Intent putExtra(String name, Serializable value)
intent .putExtra("person_test", person);
startActivity(intent);
}
});
}
}
public class SecondActivity extends Activity{
private TextView mTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
mTv = (TextView) findViewById(R.id.mTv);
Intent intent = getIntent();
// 关键方法:getSerializableExtra ,我们的类是实现了Serializable接口的,所以写这个方法获得对象
Person person = (Person)intent.getSerializableExtra("person_test");
mTv.setText("名字:"+person .getName()+"==="+"年龄:"+person .getAge());
}
}
Android专用的Parcelable的序列化:
public class Pen implements Parcelable{
private String color;
private int size;
// 系统自动添加,给createFromParcel里面用
protected Pen(Parcel in) {
color = in.readString();
size = in.readInt();
}
public static final Creator<Pen> CREATOR = new Creator<Pen>() {
/**
*
* @param in
* @return
* createFromParcel()方法中我们要去读取刚才写出的name和age字段,
* 并创建一个Person对象进行返回,其中color和size都是调用Parcel的readXxx()方法读取到的,
* 注意这里读取的顺序一定要和刚才写出的顺序完全相同。
*/
@Override
public Pen createFromParcel(Parcel in) {
return new Pen(in); // 在构造函数里面完成了 读取 的工作
}
//供反序列化本类数组时调用的
@Override
public Pen[] newArray(int size) {
return new Pen[size];
}
};
@Override
public int describeContents() {
return 0; // 内容接口描述,默认返回0即可。
}
// 读数据进行恢复
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(color);
dest.writeInt(size);
}
public Pen() {
}
public Pen(String color, int size) {
this.color = color;
this.size = size;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}
在activity中:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 采用Parcelable的方式
findViewById(R.id.mTv).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,ThirdActivity.class);
Pen pen = new Pen();
pen .setColor("red");
pen .setSize(8);
// public Intent putExtra(String name, Parcelable value)
intent .putExtra("pen_test",pen );
startActivity(intent);
}
});
}
}
public class ThirdActivity extends Activity{
private TextView mTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third);
Pen pen = (Pen)getIntent().getParcelableExtra("pen_test");
mTv = (TextView) findViewById(R.id.mTv);
mTv .setText("颜色:"+pen.getColor()+"==="+"大小:"+pen.getSize());
}
}