为什么序列化:
1、当我们需要在不同的Activity之间使用intent传递对象的时候就需要把这个对象序列化然后再放入intent当中,同样在使用Binder传递数据的时候也需要序列化
2、需要将对象永久保存在存储设备上或者通过网络传输。
3、跨进程通信的时候
序列化的方式:
1、使用JAVA中的序列化接口:Serializable
2、使用Android的序列化接口:Parcelable
两种方式的优缺点:
Serializable是JAVA中的序列化接口,使用非常简单但是开销更大,序列化和反序列化都会进行大量的I/O操作。
Parcelable是Android推荐的序列化方式,主要用在内存序列化上,使用起来稍微麻烦,但是效率更高。
将对象序列化到存储设备或者将对象序列化后通过网络传输首选Serializable.
使用方式:
Parcelable:
package com.example.eventbus.remoteviews;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by LHD on 2016/6/23.
*/
public class User implements Parcelable {
private int userId;
private String userName;
private boolean isMale;
public User(int userId, String userName, boolean isMale) {
this.userId = userId;
this.userName = userName;
this.isMale = isMale;
}
protected User(Parcel in) {
//顺序要和序列化的顺序保持一致
userId = in.readInt();
userName = in.readString();
isMale = in.readInt() == 1;
}
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.writeInt(userId);
dest.writeString(userName);
dest.writeInt(isMale ? 1 : 0);
}
}
Serializable:
package com.example.eventbus.remoteviews;
import java.io.Serializable;
/**
* Created by LHD on 2016/6/23.
*/
public class User2 implements Serializable{
//我们应该手动指定serialVersionUID的值
private static final long serialVersionUID = 1L;
private int userId;
private String userName;
private boolean isMale;
}
serialVersionUID :的作用是为反序列化提供依据。
序列化的时候系统会把当前类的serialVersionUID 值写入一个文件中,
当反序列化的时候系统会检测文件里保存的这个值是否和当前类的serialVersionUID 一致,如果一致就说明序列化的类和当前类的版本是相同的,就可以成功的反序列化。如果不一致就说明当前类发生了一些改动,就无法成功反序列化,程序就会crash。
比如我们升级了APP,这个时候APP相同的类里多了一个成员变量,如果没有这个ID值就会导致反序列化失败而导致程序crash。另外一种情况是类名发生变化,即使serialVersionUID 值一样还是会序列化失败。
注:
静态变量成员属于类不属于对象,不参与序列化。
用transient关键字标记的成员变量也不参与序列化。