前言:抱着最起碼的要求盡力去做好每一件事 ! ——秋不白
內容如題,僅個人探討,以下代碼都測試通過。
記錄一次面試經歷:面試官問到Serializable和Parcelable 的主要區別是什麼,我說把知道的說了一遍,效率,S屬於java api,P屬於Android ,以及序列化的使用場景。他說不對,然後說S是系列化到磁盤,P是序列化到內存。我就百思不得其姐,決定好好研究一下。
查找資料 以及根據AS自動生成的代碼,可以理解,Parcelable的序列化和反序列化操作實際是,Parcel內部包裝了可序列化的數據,也就是說序列化的時候,將數據放入,parcel的write方法,反序列化是通過CREATOR來完成的,通過獲取當前線程的上下文加載器,並通過parcel的read方法,來完成反序列化操作。代碼如下
Person 實體類
/**
* Desc:
*
* @author: RedRose
* Date: 2019/5/3
* Email: [email protected]
*/
public class Person implements Parcelable {
private int age;
private String name;
public Person(int age, String name) {
this.age = age;
this.name = name;
}
private Person(Parcel in) {
age = in.readInt();
name = in.readString();
}
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(age);
dest.writeString(name);
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
具體的序列化和反序列化
//將parcelable 對象序列化到磁盤
case R.id.testParcelable:
File file = new File(PathUtil.getAppDocPath() + "testParcelable.txt");
try {
if (!file.exists()) {
file.createNewFile();
}
Person p = new Person(1, "XueQin");
FileOutputStream out = (new FileOutputStream(file));
BufferedOutputStream bos = new BufferedOutputStream(out);
Parcel parcel = Parcel.obtain();
parcel.writeParcelable(p,0);
bos.write(parcel.marshall());
bos.flush();
bos.close();
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
//反序列化parcelable對象
case R.id.readParcelable:
try {
File file2 = new File(PathUtil.getAppDocPath() + "testParcelable.txt");
FileInputStream in = new FileInputStream(file2);
byte[] bytes = new byte[in.available()];
in.read(bytes);
Parcel parcel = Parcel.obtain();
parcel.unmarshall(bytes, 0, bytes.length);
parcel.setDataPosition(0);
Person person = parcel.readParcelable(Thread.currentThread().getContextClassLoader());
in.close();
LogUtils.e(TAG, person.toString());
} catch (IOException e) {
e.printStackTrace();
}
break;
以及parcel的readParcelable的源碼,可以參考下,通過當前線程的上下文類加載器獲取到CREAOR對象。
@SuppressWarnings("unchecked")
public final <T extends Parcelable> T readParcelable(ClassLoader loader) {
Parcelable.Creator<?> creator = readParcelableCreator(loader);
if (creator == null) {
return null;
}
if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
Parcelable.ClassLoaderCreator<?> classLoaderCreator =
(Parcelable.ClassLoaderCreator<?>) creator;
return (T) classLoaderCreator.createFromParcel(this, loader);
}
return (T) creator.createFromParcel(this);
}
總結:知識如浩瀚的海洋,加油吧,我們一起。