前言
Parcelable是Android为我们提供的序列化的接口。
下面我们从几个问题出发去深入了解它。
- parcelable的作用?
- parcelable如何序列化?
- parcelable如何反序列化?
- 什么时候使用parcelable比较好?
1 parcelable的作用
将对象变成字节序列,便于存储,网络传输对象,进程间传递对象。
2 parcelable序列化与反序列化
实体类实现Parcelable后,Android Studio会提示自动补全必要的方法。
public class User implements Parcelable {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
// TODO 读写顺序必须一致,否则会出现数据紊乱。
// 从Parcel对象里读出数据,赋值给成员变量
protected User(Parcel in) {
name = in.readString();
age = in.readInt();
}
// 序列化
// 把属性写入Parcel对象中
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
@Override
public int describeContents() {
return 0;
} // 一般为0,只有一些特殊的类返回1
// 反序列化
// 必须实现 CREATOR 名称不可变
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];
}
};
}
3 进程间传递对象
大致了解了Parcelable的序列化后,我们以进程间传递对象来实际应用一下。
通过intent传递对象
// User对象延续使用上面那个
User user = new User("张三", 78);
Intent intent = new Intent(getActivity(), TestActivity.class);
intent.putExtra("user", user);
startActivity(intent);
创建TestActivity,独立进程,接收对象并打印
public class TestActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
User user = getIntent().getParcelableExtra("user");
Log.i("接收对象:", user.toString());
}
}
// TestActivity放到单独的进程中
<activity
android:name=".TestActivity"
android:process=":test"/>
结果
4 什么时候使用Parcelable比较好
相比与Serializable,Parcelable经过Google工程师的定制处理后,IO效率明显高得多。所以博主的建议是,内存间的对象传递最好用Parcelable,用Serializable也可以。
但是,如果做持久化存储或网络间的传输,用Serializable,它是通用的序列化机制。
下面是Google官方的说法。
Parcel is not a general-purpose serialization mechanism. This class (and the corresponding Parcelable API for placing arbitrary objects into a Parcel) is designed as a high-performance IPC transport. As such, it is not appropriate to place any Parcel data in to persistent storage: changes in the underlying implementation of any of the data in the Parcel can render older data unreadable.
Parcel不是通用的序列化机制。此类(以及Parcelable用于将任意对象放入Parcel的相应 API)被设计为高性能IPC传输。因此,将任何Parcel数据放置到持久性存储中是不合适的:对Parcel中任何数据的基础实现进行更改会导致较旧的数据不可读。