本文的合集已經(jīng)編著成書,高級Android開發(fā)強(qiáng)化實(shí)戰(zhàn)衷旅,歡迎各位讀友的建議和指導(dǎo)捐腿。在京東即可購買:https://item.jd.com/12385680.html
在進(jìn)程或頁面通信時(shí)需要使用Intent傳遞數(shù)據(jù); 在對象持久化時(shí)需要存儲數(shù)據(jù). 對于復(fù)雜的對象, 進(jìn)行序列化才可傳遞或存儲, 可以使用Java的Serializable
方式或Android的Parcelable
方式. 本文介紹Serializable和Parcelable的使用方式.
本文源碼的GitHub下載地址
Serializable
序列化User類, 實(shí)現(xiàn)Serializable
接口即可. 注意serialVersionUID用于輔助序列化與反序列化, 只有相同時(shí), 才會正常進(jìn)行. 如不指定, 則系統(tǒng)會自動生成Hash值, 修改類代碼, 可能會導(dǎo)致無法反序列化, 所以強(qiáng)制指定.
public class UserSerializable implements Serializable {
// 標(biāo)準(zhǔn)序列ID, 用于判斷版本
private static final long serialVersionUID = 1L;
public int userId;
public String userName;
public boolean isMale;
public UserSerializable(int userId, String userName, boolean isMale) {
this.userId = userId;
this.userName = userName;
this.isMale = isMale;
}
}
序列化對象, 使用ObjectOutputStream
存儲已經(jīng)序列化的對象數(shù)據(jù), 通過writeObject
寫入對象.
public void serialIn(View view) {
Context context = view.getContext();
File cache = new File(context.getCacheDir(), "cache.txt");
try {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(cache));
UserSerializable user = new UserSerializable(0, "Spike", false);
out.writeObject(user);
out.close();
Toast.makeText(context, "序列化成功", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
緩存文件位置:
new File(context.getCacheDir(), "cache.txt")
.
反序列對象, 使用ObjectInputStream
反序列化對象, 通過readObject
讀取對象的持久化信息.
public void serialOut(View view) {
Context context = view.getContext();
File cache = new File(context.getCacheDir(), "cache.txt");
UserSerializable newUser = null;
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream(cache));
newUser = (UserSerializable) in.readObject();
in.close();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(context, "請先序列化", Toast.LENGTH_SHORT).show();
}
if (newUser != null) {
String content = "序號: " + newUser.userId
+ ", 姓名: " + newUser.userName
+ ", 性別: " + (newUser.isMale ? "男" : "女");
mSerialTvContent.setText(content);
} else {
mSerialTvContent.setText("無數(shù)據(jù)");
}
}
Parcelable
Android推薦的序列化對象方式. 實(shí)現(xiàn)Parcelable
接口, writeToParcel
寫入對象的變量, UserParcelable
提供解析對象方式. CREATOR
是創(chuàng)建序列化對象的匿名類, 必須實(shí)現(xiàn), 包含創(chuàng)建單個(gè)對象與數(shù)組的方式. describeContents
只有在含有文件描述符是返回1, 默認(rèn)都是返回0, 不需要修改.
public class UserParcelable implements Parcelable {
public int userId;
public String userName;
public boolean isMale;
public BookParcelable book;
public UserParcelable(int userId, String userName, boolean isMale, String bookName) {
this.userId = userId;
this.userName = userName;
this.isMale = isMale;
this.book = new BookParcelable(bookName);
}
@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);
dest.writeParcelable(book, 0);
}
public static final Parcelable.Creator<UserParcelable> CREATOR = new Parcelable.Creator<UserParcelable>() {
@Override public UserParcelable createFromParcel(Parcel source) {
return new UserParcelable(source);
}
@Override public UserParcelable[] newArray(int size) {
return new UserParcelable[size];
}
};
private UserParcelable(Parcel source) {
userId = source.readInt();
userName = source.readString();
isMale = source.readInt() == 1;
book = source.readParcelable(Thread.currentThread().getContextClassLoader());
}
}
使用Intent傳遞對象數(shù)據(jù), 編號0, 姓名Spike, 性別女, 喜歡書籍三國演義.
public void parcelSend(View view) {
Intent intent = new Intent(PASS_PARCEL_FILTER);
intent.putExtra(PARCEL_EXTRA, new UserParcelable(0, "Spike", false, "三國演義"));
mLBM.sendBroadcast(intent);
}
解析廣播Intent的數(shù)據(jù), 使用getParcelableExtra
方法即可.
private BroadcastReceiver mParcelReceiver = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) {
UserParcelable newUser = intent.getParcelableExtra(PARCEL_EXTRA);
if (newUser != null) {
String content = "序號: " + newUser.userId
+ ", 姓名: " + newUser.userName
+ ", 性別: " + (newUser.isMale ? "男" : "女")
+ ", 書: " + newUser.book.bookName;
Toast.makeText(context, content, Toast.LENGTH_SHORT).show();
mParcelTvContent.setText(content);
}
}
};
效果
Serializable序列化需要大量的IO操作, Parcelable序列化雖然使用復(fù)雜, 但是效率很高, 是Android開發(fā)的首選. Parcelable主要應(yīng)用于內(nèi)存序列化, 如Intent廣播等.
OK, that's all! Enjoy it!