一、Parcelable
和Serializable
物件的序列化是把Java
物件轉化為位元組序列並儲存至一個儲存媒介(硬碟或者記憶體)的過程,反序列化則是把位元組序列恢復為Java
物件的過程,但它們僅處理Java
變數而不處理方法。
序列化的原因:
- 永久性儲存物件,儲存物件的位元組序列到本地檔案中。
Serializable
- 通過序列化物件在網路中傳遞物件。
Serializable
- 通過序列化在程式間傳遞物件。
Parcelable
兩種序列化的區別:
Serializable
只需要對某個類以及它的屬性實現Serializable
介面即可,它的缺點是使用了反射,序列化的過程比較慢,這種機制會在序列化的時候建立許多的臨時物件,容易引發頻繁的gc
。- 而
Parcelable
是Android
平臺特有的,在使用記憶體的時候效能更好,但Parcelable
不能使用在要將資料儲存在磁碟的情況下,因為Parcelable
不能很好的保證資料的持續性在外界有變化的情況。
二、序列化在Android
平臺上的應用
2.1 通過intent
傳遞複雜物件
intent
支援傳遞的資料型別包括:
- 基本型別的資料、及其陣列。
String/CharSequence
型別的資料、及其陣列。Parcelable/Serializable
,及其陣列/列表資料。
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) {
}
}
}
複製程式碼