Serializable(Java自带):
Serializable是序列化的意思,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。
Parcelable(android 专用):
除了Serializable之外,使用Parcelable也可以实现相同的效果,
不过不同于将对象进行序列化,Parcelable方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了。
选择序列化方法的原则
1)在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。
2)Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3)Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性,在外界有变化的情况下。因此尽管Serializable效率低点,但此时还是建议使用Serializable 。
下面开始Parcelable之旅。一个Person类是实现Parcelable接口
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by wangpeiyu on 2017/6/1.
*/
public class Person implements Parcelable {
/**
* 供重新组合对象是调用
* @param in
*/
protected Person(Parcel in) {
/**
* 这里读取数据时要和Parcelable方法写数据的顺序保持一致
*/
}
public static final Creator<Person> CREATOR = new Creator<Person>() {
/**
*重新组合本对象时调用
* @param in
* @return
*/
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
/**
*重新组合本对象数组时调用
* @param size
* @return
*/
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
@Override
public int describeContents() {
return 0;
}
/**
* 将本对象拆包成常用类型,用于传输
* @param dest
* @param flags
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
}
}
我们要实现这3个方法和一个内部类。
现在实现这几个方法和内部类中的方法。
package com.example.wangpeiyu.helloworld.enity;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by wangpeiyu on 2017/6/1.
*/
public class Person implements Parcelable {
private String firstName;
private String lastName;
private int age;
private String[] childName;
public Person(String firstName, String lastName, int age, String[] childName) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.childName = childName;
}
public Person() {
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public String[] getChildName() {
return childName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setAge(int age) {
this.age = age;
}
public void setChildName(String[] childName) {
this.childName = childName;
}
/**
* 供重新组合对象是调用
* @param in
*/
protected Person(Parcel in) {
/**
* 这里读取数据时要和Parcelable方法写数据的顺序保持一致,而且类型也要保持一致
*/
this.firstName=in.readString();
this.lastName=in.readString();
this.age=in.readInt();
//需要先创建这个数组先,才可以将数组传递进去
childName=new String[3];
in.readStringArray(childName);//因为在方法中是用writeStringArray方法写的,所以在读的时候也要用StringArray方式读
}
public static final Creator<Person> CREATOR = new Creator<Person>() {
/**
*
* @param in
* @return
*/
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
/**
* 描述内容,可写可不写
* @return
*/
@Override
public int describeContents() {
return 0;
}
/**
* 将本对象拆包成常用类型,用于传输
* @param dest
* @param flags
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(firstName);
dest.writeString(lastName);
dest.writeInt(age);
dest.writeStringArray(childName);
}
}
两个简单界面
MainActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
//使用Lambda表达式,完成点击事件的处理
button.setOnClickListener(v->{
Person person=new Person("wang","peiyu",29,new String[]{"xiaoming","xiaohua","xiaogao"});
Intent intent= new Intent(this,Main2Activity.class);
Bundle bundle=new Bundle();
bundle.putParcelable("person",person);
intent.putExtras(bundle);
startActivity(intent);
});
}
另一个界面Main2Activity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Intent intent=getIntent();
Bundle bundle=intent.getExtras();
Person person= (Person) bundle.get("person");
Toast.makeText(this,person.getFirstName()+" "+person.getLastName()+" age is "+person.getAge()+" childs are "+ Arrays.toString(person.getChildName()),Toast.LENGTH_SHORT).show();
}
这样就实现了对象的传输。
重点:
拆对象,写的顺序和类型,在之后的 protected Person(Parcel in)构造函数中要严格保持一致。
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(firstName);
dest.writeString(lastName);
dest.writeInt(age);
dest.writeStringArray(childName);
}
重新组合对象。
protected Person(Parcel in) {
/**
* 这里读取数据时要和Parcelable方法写数据的顺序保持一致,而且类型也要保持一致
*/
this.firstName=in.readString();
this.lastName=in.readString();
this.age=in.readInt();
//需要先创建这个数组先,才可以将数组传递进去
childName=new String[3];
in.readStringArray(childName);//因为在方法中是用writeStringArray方法写的,所以在读的时候也要用StringArray方式读
}
这就是Parcelable接口的简单用法。