前言
在介绍Serializable和Parcelable两种序列化方式之前,我们先来了解下什么是序列化,什么是反序列化,为什么要序列化?
序列化:
把对象转换成字节系列的过程叫做对象的序列化。
反序列化:
把字节序列恢复成对象的过程叫做对象的反序列化。
序列化的主要用途:
(1)把对象永久的存放在磁盘中,在Android系统中就是存放在sdcard中,通常是存放在一个文件中。
(2)在网络中传输对象。
例如:在web服务器中的session对象,一个用户访问,就会有一个session对象。当数十万的用户并发访问,就会产生数十万个session对象,内存一时承受不住那么多对象,web容器就会把session对象序列化成字节序列存放到磁盘中,当需要用到的时候,在恢复成对象。
在跨进程通信的时候,因为数据是在网络中传输的,网络传输只能传输字节序列,所以需要把对象序列化成字节序列进行传输。
Serializable
Serializable是Java提供的序列化接口,下面介绍一下使用方法。
public class UserDto implements Serializable {
private static final long serialVersionUID = -7007857824834322776L;
private String username;
private String password;
public UserDto(String username, String password) {
this.username = username;
this.password = password;
}
public UserDto() {
}
public static long getSerialVersionUID() {
return serialVersionUID;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
首先在实体类中实现Serializable 接口,然后声明serialVersionUID 变量。接下来我们介绍如何把对象序列化到sdcard中的文件中以及把对象反序列化出来。
序列化到文件中:
ivEtxt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
UserDto userDto = new UserDto("admin", "123456");
try {
ObjectOutputStream stream =
new ObjectOutputStream(new FileOutputStream(FileUtils.getCachFilePath(MainActivity.this)+"user.txt"));
stream.writeObject(userDto);
stream.close();
Log.e(TAG, "onClick: 写入成功");
} catch (Exception e) {
Log.e(TAG, "onClick: "+e.getMessage() );
}
}
反序列化成对象:
ivEtxt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//UserDto userDto = new UserDto("admin", "123456");
try {
// ObjectOutputStream stream =
// new ObjectOutputStream(new FileOutputStream(FileUtils.getCachFilePath(MainActivity.this)+"user.txt"));
// stream.writeObject(userDto);
// stream.close();
// Log.e(TAG, "onClick: 写入成功");
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(FileUtils.getCachFilePath(MainActivity.this)+"user.txt"));
UserDto userDto = (UserDto) inputStream.readObject();
inputStream.close();
Log.e(TAG, "onClick: "+userDto.getUsername()+":"+userDto.getPassword() );
} catch (Exception e) {
Log.e(TAG, "onClick: "+e.getMessage() );
}
}
});
Parcelable
以上我们介绍了Serializable,Java中的序列化方式,现在我们来介绍下Parcelable,Parcelable是在AndroidSdk中。接下来我们介绍使用方法:
package com.mujin.keji.myapplication;
import android.os.Parcel;
import android.os.Parcelable;
public class UserBean implements Parcelable {
private String username;
private String password;
public UserBean() {
}
public UserBean(String username, String password) {
this.username = username;
this.password = password;
}
protected UserBean(Parcel in) {
username = in.readString();
password = in.readString();
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(username);
dest.writeString(password);
}
public static final Creator<UserBean> CREATOR = new Creator<UserBean>() {
@Override
public UserBean createFromParcel(Parcel in) {
return new UserBean(in);
}
@Override
public UserBean[] newArray(int size) {
return new UserBean[size];
}
};
}
实体类实现Parcelable接口,并实现相应的方法。看上面的代码所示。我们看到使用Parcelable方式进行序列化,需要重写几个方法,和成员变量。其中序列化功能由writeToParcel完成,反序列化由CREATOR 完成,describeContents用来描述内容。
Serializable和Parcelable应该怎么选择?
既然Serializable和Parcelable都可以序列化,都可以用于Intent传输数据,那么二者怎么选择呢?首先Serializable是Java中的接口,序列化和反序列过程都需要大量的I/O操作,开销很大。而Parcelable是Android中的序列化方式,更加适用于Android平台。它的缺点就是适用起来比较麻烦,但是使用的效率很高。那么我们应该怎么选择呢?
一般情况下我们首先选择Parcelable,Parcelable主要用于在内存上的序列化,比如在Intent之间传输数据的时候,可以用Parcelable。如果要在磁盘中或者网络传输的序列化,也可以用Parcelable,但是操作很麻烦,这个时候我们应该选择Serializable。
网友评论