在android中的活动之间传递对象(示例)
Zas12357386
・7 分钟阅读
使用intent传递数据
在activity之间传递简单的数据类型(字符串,int,double...等等)很容易,我们可以使用唯一的键将它们放到Intent中,并将它发送到另一个Activity 。
但是,在activity之间传递自定义对象时它有点复杂,这是使用serialization的原因。
什么是序列化?
序列化将数据快速,高效,内部表示转换为可以保存在持久存储中或通过网络传输的东西。
将数据转换为它序列化形式通常称为
marshaling
,将它转换回它生存状态,在内存表示中称为反序列化或unmarshaling
。
有关序列化的更多信息- https://www.inkling.com/read/programming-android-mednieks-1st/chapter-6/serialization
- 在android中,有两种实现java对象
marshaling
和unmarshaling
的方法,
- Serializable(将对象序列化)
- Parcelable (将对象作为parcelable)
Serializable vs Parcelable
Serializable是一个标记接口,用户不能根据它要求封送数据,因此当对象Serializable Java将自动序列化它。
Parcelable是android自己的序列化协议,在Parcelable中,开发人员编写自定义代码来封送和解析。 因此,与序列化相比,它创建较少的垃圾对象,
由于Parcelable的自定义实现,所以,它的性能非常高,
我们强烈推荐在android中序列化对象时使用Parcelable注入,
Parcelable对象
当需要在activity之间传递自定义对象时,我们可以将对象标记为Parcelable (实现parcelable接口)。 然后使用
intent.putExtra
方法将对象放入到Intent中,下面是parcelable对象(
User
)的示例实现,
https://github.com/erangaeb/dev-notes/blob/master/android-parcelable/User.java
这是一个简单的对象,它可以,
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<User> CREATOR = new Parcelable.Creator<User>() {
public User createFromParcel(Parcel in) {
return new User(in);
}
public User[] newArray(int size) {
return new User[size];
}
};
这个用户对象是一个简单的parcelabel对象,可能有更复杂的对象,对于一个实例,你有一个引用另一个对象的对象。 在这种情况下,它们都需要是Parcelable
下面是更复杂的parcelable对象(
Sensor
)的示例,
https://github.com/erangaeb/dev-notes/blob/master/android-parcelable/Sensor.java
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<User>();
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<User> userList = new ArrayList<User>();
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" )