原文链接
这篇主要介绍如何在Android中实现Parcelable
Bundle对象传递数据
我们都知道,可以使用Bundle对象在Andriod各大组建之间传递数据,使用Bundle.putXXX(KEY, VALUE)
可以存放一些基本数据类型以及封装类型,以下是Bundle对象可以存储的数据类型
- primitives(基本数据类型)
- String
- Serializable
- Parcelable
存储的时候使用键值的方式进行存储并传递
如果我们需要使用Bundle传递对象,我们可以
implements Serializable
,或者implements Parcelable
实现Serializable接口
这种方式非常简单,我们直接实现Serializable
接口就行,这个接口是一个空的接口,所以我们不需要做任何操作,如果有必要我们可以定义一个serialVersionUID
public interface Serializable {
}
我们常见的File
类就实现了这个接口
public class File
implements Serializable, Comparable<File>
{
...
}
实现Parcelable接口
这个相比与 Serializable稍微复杂一点,不过是 Google
推荐的方式,我们来看看官方给的一个例子
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();
}
}
这个例子中的对象只包含了一个属性mData
,我们在看一个例子
public class User implements Parcelable {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
protected User(Parcel in) {
name = in.readString();
age = in.readInt();
}
public static final Creator<User> CREATOR = new Creator<User>() {
@Override
public User createFromParcel(Parcel in) {
return new User(in);
}
@Override
public User[] newArray(int size) {
return new User[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
传递Parcelable对象并解析
传递
User user = new User("shellhub", 23);
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra(KEY, user);
startActivity(intent);
解析
User user = getIntent().getExtras().getParcelable(KEY);
因为方法实现了泛型,所以不需要类型转换
public <T extends Parcelable> T getParcelable(@Nullable String key) {
Serializable 和 Parcelable之间的区别
- Parcelable比 Serializable快
- Parcelable需要花更多的时间写更多的代码
- Serializable实现更加简单
- Serializable接口会创建大量临时对象并导致相当多的垃圾回收
- Parcelable数组可以通过android中的Intent传递
public @NonNull Intent putExtra(String name, Parcelable[] value) {
效率对比
Q&A
对象中定义的CREATOR
可以改为其他名字么?
- 不可以,如果定义为其他名字会报以下错误
Caused by: android.os.BadParcelableException: Parcelable protocol requires a Parcelable.Creator object called CREATOR on class com.github.shellhub.parcelable.User
示例代码
https://github.com/shellhub/android-samples/tree/master/Parcelable