一、Parcelable
和Serializable
對象的序列化是把Java
對象轉(zhuǎn)化為字節(jié)序列并存儲至一個存儲媒介(硬盤或者內(nèi)存)的過程纵东,反序列化則是把字節(jié)序列恢復為Java
對象的過程,但它們僅處理Java
變量而不處理方法式曲。
序列化的原因:
- 永久性保存對象,保存對象的字節(jié)序列到本地文件中。
Serializable
- 通過序列化對象在網(wǎng)絡中傳遞對象楼肪。
Serializable
- 通過序列化在進程間傳遞對象。
Parcelable
兩種序列化的區(qū)別:
-
Serializable
只需要對某個類以及它的屬性實現(xiàn)Serializable
接口即可惹悄,它的缺點是使用了反射春叫,序列化的過程比較慢,這種機制會在序列化的時候創(chuàng)建許多的臨時對象,容易引發(fā)頻繁的gc
暂殖。 - 而
Parcelable
是Android
平臺特有的价匠,在使用內(nèi)存的時候性能更好,但Parcelable
不能使用在要將數(shù)據(jù)存儲在磁盤的情況下呛每,因為Parcelable
不能很好的保證數(shù)據(jù)的持續(xù)性在外界有變化的情況踩窖。
二、序列化在Android
平臺上的應用
2.1 通過intent
傳遞復雜對象
intent
支持傳遞的數(shù)據(jù)類型包括:
- 基本類型的數(shù)據(jù)晨横、及其數(shù)組洋腮。
-
String/CharSequence
類型的數(shù)據(jù)、及其數(shù)組手形。 -
Parcelable/Serializable
啥供,及其數(shù)組/列表數(shù)據(jù)。
2.2 SharePreference
存儲復雜對象
三库糠、Serializable
和Parcelable
3.1 使用Serializable
的讀寫操作
首先定義我們要序列化的對象伙狐。
public class SBook implements Serializable {
public int id;
public String name;
}
進行讀寫操作:
private void readSerializable() {
ObjectInputStream object = null;
try {
FileInputStream out = new FileInputStream(Environment.getExternalStorageDirectory() + "/sbook.txt");
object = new ObjectInputStream(out);
SBook book = (SBook) object.readObject();
if (book != null) {
Log.d(TAG, "book, id=" + book.id + ",name=" + book.name);
} else {
Log.d(TAG, "book is null");
}
} catch (Exception e) {
Log.d(TAG, "readSerializable:" + e);
} finally {
try {
if (object != null) {
object.close();
}
} catch (Exception e) {
Log.d(TAG, "readSerializable:" + e);
}
}
}
private void writeSerializable() {
SBook book = new SBook();
book.id = 1;
book.name = "SBook";
ObjectOutputStream object = null;
try {
FileOutputStream out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/sbook.txt");
object = new ObjectOutputStream(out);
object.writeObject(book);
object.flush();
} catch (Exception e) {
Log.d(TAG, "writeSerializable:" + e);
} finally {
try {
if (object != null) {
object.close();
}
} catch (Exception e) {
Log.d(TAG, "writeSerializable:" + e);
}
}
}
3.2 使用Parcelable
的讀寫操作
定義序列化對象:
public class PBook implements Parcelable {
public int id;
public String name;
public PBook(int id, String name) {
this.id = id;
this.name = name;
}
private PBook(Parcel in) {
id = in.readInt();
name = in.readString();
}
public static final Parcelable.Creator<PBook> CREATOR = new Parcelable.Creator<PBook>() {
@Override
public PBook[] newArray(int size) {
return new PBook[size];
}
@Override
public PBook createFromParcel(Parcel source) {
return new PBook(source);
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(name);
}
}
寫入和讀取:
private Intent writeParcelable() {
PBook tony = new PBook(1, "tony");
PBook king = new PBook(2, "king");
ArrayList<PBook> list = new ArrayList<>();
list.add(tony);
list.add(king);
Intent intent = new Intent();
intent.putParcelableArrayListExtra("PBook", list);
return intent;
}
private void readParcelable(Intent intent) {
if (intent != null) {
ArrayList<PBook> list = intent.getParcelableArrayListExtra("PBook");
if (list != null) {
for (PBook book : list) {
Log.d(TAG, "readParcelable, id=" + book.id + ", name=" + book.name);
}
}
}
}
四瞬欧、SharePreference
存儲復雜對象
//obejct -> ObjectOutputStream(ByteArrayOutputStream) -> ByteArrayOutputStream() -> byte[] -> String -> sp
private void writeSP() {
SBook book = new SBook();
book.id = 2;
book.name = "sp";
SharedPreferences sp = getSharedPreferences("SBookSP", MODE_PRIVATE);
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
ObjectOutputStream object = new ObjectOutputStream(os);
object.writeObject(book);
String base64 = new String(Base64.encode(os.toByteArray(), Base64.DEFAULT));
SharedPreferences.Editor editor = sp.edit();
editor.putString("SBook", base64);
editor.apply();
} catch (Exception e) {}
}
//sp -> string -> byte[] -> ByteArrayInputStream(byte[]) -> ObjectInputStream(ByteArrayInputStream) -> object
private void readSP() {
SharedPreferences sp = getSharedPreferences("SBookSP", MODE_PRIVATE);
String sbook = sp.getString("SBook", "");
if (sbook.length() > 0) {
byte[] base64 = Base64.decode(sbook.getBytes(), Base64.DEFAULT);
ByteArrayInputStream is = new ByteArrayInputStream(base64);
try {
ObjectInputStream object = new ObjectInputStream(is);
SBook book = (SBook) object.readObject();
if (book != null) {
Log.d(TAG, "readSP, id=" + book.id + ", name=" + book.name);
}
} catch (Exception e) {
}
}
}