使用intent传递数据在activity之间传递简单的数据类型(字符串,int,double...等等)很容易,我们可以使用唯一的键将它们放到Intent中,并将它发送到另一个Activity 。
但是,在activity之间传递自定义对象时它有点复杂,这是使用serialization的原因。
什么是序列化?序列化将数据快速,高效,内部表示转换为可以保存在持久存储中或通过网络传输的东西。
将数据转换为它序列化形式通常称为marshaling ,将它转换回它生存状态,在内存表示中称为反序列化或unmarshaling 。在android中,有两种实现java对象marshaling和unmarshaling的方法,Serializable(将对象序列化)
Parcelable (将对象作为parcelable)
Serializable vs ParcelableSerializable是一个标记接口,用户不能根据它要求封送数据,因此当对象Serializable Java将自动序列化它。
Parcelable是android自己的序列化协议,在Parcelable中,开发人员编写自定义代码来封送和解析。 因此,与序列化相比,它创建较少的垃圾对象,
由于Parcelable的自定义实现,所以,它的性能非常高,
我们强烈推荐在android中序列化对象时使用Parcelable注入,
Parcelable对象当需要在activity之间传递自定义对象时,我们可以将对象标记为Parcelable (实现parcelable接口)。 然后使用intent.putExtra方法将对象放入到Intent中,
下面是parcelable对象(User )的示例实现,这是一个简单的对象,它可以,User对象实现为Parcelable 。
有两种方法可以从Parcelable接口describeContents和writeToParcel中,writeToParcel方法中的实际对象序列化。/**
* Define the kind of object that you gonna parcel,
* You can use hashCode() here
*/
@Override
public int describeContents() {
return 0;
}/**
* Actual object serialization happens here, Write object content
* to parcel, reading should be done according to this write order
* param dest - parcel
* param flags - Additional flags about how the object should be written
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(id);
dest.writeString(username);
dest.writeString(email);
dest.writeString(password);
}对象需要有Parcelable.Creator ,Android需要这个字段来创建新对象,也可以单独或作为数组,/**
* This field is needed for Android to be able to
* create new objects, individually or as arrays
*
* If you don't do that, Android framework will raises an exception
* Parcelable protocol requires a Parcelable.Creator object
* called CREATOR
*/
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public User createFromParcel(Parcel in) {
return new User(in);
}
public User[] newArray(int size) {
return new User[size];
}
};这个用户对象是一个简单的parcelabel对象,可能有更复杂的对象,对于一个实例,你有一个引用另一个对象的对象。 在这种情况下,它们都需要是Parcelable
下面是更复杂的parcelable对象(Sensor )的示例,Sensor对象包含几个特殊字段,1. User object(user)
2. User list(sharedUsers)
3. boolean field(isMySensor)当将传感器的用户对象写入包时,它使用,dest.writeParcelable(user, flags);从包读取User对象时需要类装入器,this.user = in.readParcelable(User.class.getClassLoader());在将用户列表(sharedUsers )写入包时,它使用,dest.writeTypedList(sharedUsers);从包读取用户列表(sharedUsers )时需要User.CREATOR实例,this.sharedUsers = new ArrayList();
in.readTypedList(sharedUsers, User.CREATOR);我们将它转换为整数值,并且将它保存为整数(因为没有任何方法直接向包写入布尔值),而不是将布尔值写入包,dest.writeInt(isMySensor? 1 : 0);读取布尔值时,我们从保存的整数中得到布尔值,this.isMySensor = (in.readInt()!= 0);
将对象传递给在启动Activity中,我们可以将parcelable对象设置为,User user = new User(" 1" ," u" ," u" ," u" );
ArrayList userList = new ArrayList();
Sensor sensor = new Sensor(" 1" ," s" ," s" , true, user, userList);
intent.putExtra(" com.score.senzors.pojos.Sensor" , sensor);在目标Activity中,我们可以从Intent附加(绑定)获取parcelable对象,Bundle bundle = getIntent().getExtras();
Sensor sensor = bundle.getParcelable(" com.score.senzors.pojos.Sensor" )