一、构建 Bundle
从 Parcel 中解析 出 Bundle 数据。
Parce readBundle() 方法。
public final Bundle readBundle(ClassLoader loader) {
int length = readInt();
if (length < 0) {
return null;
}
final Bundle bundle = new Bundle(this, length);
if (loader != null) {
bundle.setClassLoader(loader);
}
return bundle;
}
创建 Bundle 对象
BaseBundle 类构造方法,根据数据长度,创建 ArrayMap 对象。
BaseBundle(Parcel parcelledData, int length) {
readFromParcelInner(parcelledData, length);
}
将数据源 Parcel 入参
private void readFromParcelInner(Parcel parcel, int length) {
if (length == 0) {
mParcelledData = EMPTY_PARCEL;
return;
}
...
Parcel p = Parcel.obtain();
p.setDataPosition(0);
p.appendFrom(parcel, offset, length);
...
p.setDataPosition(0);
mParcelledData = p;
}
从 Parcel 池 获取一个 Parcel,appendFrom() 入参数据源。内部赋值 mParcelledData。
构建 Bundle,并未立即解析 Parcel 数据 到 ArrayMap。
二、unparcel() 解析
unparcel() 方法,将 BaseBundle 内部 Parcel ,即 mParcelledData ,解析到 ArrayMap,在 Parcel 数据读取时用到。
synchronized void unparcel() {
synchronized (this) {
final Parcel parcelledData = mParcelledData;
//Bundle内部parcelledData是空时,不用解析
if (parcelledData == null) {
return;
}
//Bundle内部parcelledData无数据时,不用解析
if (isEmptyParcel()) {
if (mMap == null) {
mMap = new ArrayMap<>(1);
} else {
mMap.erase();
}
mParcelledData = null;
return;
}
int N = parcelledData.readInt();
ArrayMap<String, Object> map = mMap;
//Map是空时创建。
try {
parcelledData.readArrayMapInternal(map, N, mClassLoader);
} catch (BadParcelableException e) {
} finally {
mMap = map;
parcelledData.recycle();
mParcelledData = null;
}
}
}
Bundle 内部 Parcel,readArrayMapInternal() 方法。
解析完成,finally{} 释放 Parcel ,置空,因此,Intent 多次调用 getXxx() 时,在判空后不会再次 unparcel(),直接使用 ArrayMap。
void readArrayMapInternal(ArrayMap outVal, int N,
ClassLoader loader) {
int startPos;
while (N > 0) {
String key = readString();//从Parcel读取key
Object value = readValue(loader);//从Parcel读取value
outVal.append(key, value);//写入ArrayMap
N--;
}
outVal.validate();
}
遍历数量N,从 Parcel 中读取 key-value,写入 ArrayMap。
Parcel readValue() 方法
public final Object readValue(ClassLoader loader) {
int type = readInt();
switch (type) {
case VAL_NULL:
return null;
case VAL_STRING:
return readString();
case VAL_INTEGER:
return readInt();
case VAL_PARCELABLE:
return readParcelable(loader);
...
}
先读取 int 字段,JNI # nativeReadInt(),类型判断。
根据类型,调用 Parcel readXxx() 方法,JNI nativeReadXxx()方法。
Parcel readParcelable() 方法。
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);
}
根据 ClassLoader ,查找 XxxBean 实现的 Creator。
调用 createFromParcel() 方法,创建 XxxBean 实体,传入 Parcel,读取字段向实体赋值。
(和写入数据的 XxxBean 实体非同一对象)
通过 unparcel() 方法,将 Parcel 中各种类型数据,全部解析 ArrayMap 数据结构。
任重到道远
网友评论