探索下Intent.getxxxExtra()是否需要捕获异常
程序员文章站
2022-04-15 18:07:38
偷个懒:共同探索下Intent.getxxxExtra()是否需要捕获异常下面我们以getStringExtra为例,共同探索下: private Bundle mExtras; /** * Retrieve extended data from the intent. * * @param name The name of the desired item. * * @return the value of an item previo...
偷个懒:和大家共同探索下Intent.getxxxExtra()是否需要捕获异常
下面我们以getStringExtra为例,共同探索下:
private Bundle mExtras;
/**
* Retrieve extended data from the intent.
*
* @param name The name of the desired item.
*
* @return the value of an item previously added with putExtra(),
* or null if no String value was found.
*
* @see #putExtra(String, String)
*/
public @Nullable String getStringExtra(String name) {
return mExtras == null ? null : mExtras.getString(name);
}
Bundle中并没有实现getString方法,其中Bundle是继承BaseBundle的,我们去BaseBundle下看下
public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
BaseBundle 的getString要求传入的key是非空的,实际上是非常有意义的,public的接口如果我们不控制入参@Nullable,
就需要在使用入参前,对入参进行非空判断,即使不可能为空,还是需要例行判空。因为没有人知道调用该接口的
是使用者还是恶意的攻击者。
言归正传,看unparcel()方法:
/**
* Returns the value associated with the given key, or null if
* no mapping of the desired type exists for the given key or a null
* value is explicitly associated with the key.
*
* @param key a String, or null
* @return a String value, or null
*/
@Nullable
public String getString(@Nullable String key) {
unparcel();
final Object o = mMap.get(key);
try {
return (String) o;
} catch (ClassCastException e) {
typeWarning(key, o, "String", e);
return null;
}
}
@UnsupportedAppUsage
/* package */ void unparcel() {
synchronized (this) {
final Parcel source = mParcelledData;
if (source != null) {
initializeFromParcelLocked(source, /*recycleParcel=*/ true, mParcelledByNative);
} else {
if (DEBUG) {
Log.d(TAG, "unparcel "
+ Integer.toHexString(System.identityHashCode(this))
+ ": no parcelled data");
}
}
}
}
可以看见,在捕获到了BadParcelableException 后,它并没有把该异常内部消化掉,而是throw出去了。
private void initializeFromParcelLocked(@NonNull Parcel parcelledData, boolean recycleParcel,
boolean parcelledByNative) {
if (LOG_DEFUSABLE && sShouldDefuse && (mFlags & FLAG_DEFUSABLE) == 0) {
Slog.wtf(TAG, "Attempting to unparcel a Bundle while in transit; this may "
+ "clobber all data inside!", new Throwable());
}
if (isEmptyParcel(parcelledData)) {
if (DEBUG) {
Log.d(TAG, "unparcel "
+ Integer.toHexString(System.identityHashCode(this)) + ": empty");
}
if (mMap == null) {
mMap = new ArrayMap<>(1);
} else {
mMap.erase();
}
mParcelledData = null;
mParcelledByNative = false;
return;
}
final int count = parcelledData.readInt();
if (DEBUG) {
Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+ ": reading " + count + " maps");
}
if (count < 0) {
return;
}
ArrayMap<String, Object> map = mMap;
if (map == null) {
map = new ArrayMap<>(count);
} else {
map.erase();
map.ensureCapacity(count);
}
try {
if (parcelledByNative) {
// If it was parcelled by native code, then the array map keys aren't sorted
// by their hash codes, so use the safe (slow) one.
parcelledData.readArrayMapSafelyInternal(map, count, mClassLoader);
} else {
// If parcelled by Java, we know the contents are sorted properly,
// so we can use ArrayMap.append().
parcelledData.readArrayMapInternal(map, count, mClassLoader);
}
} catch (BadParcelableException e) {
if (sShouldDefuse) {
Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e);
map.erase();
} else {
throw e;
}
} finally {
mMap = map;
if (recycleParcel) {
recycleParcel(parcelledData);
}
mParcelledData = null;
mParcelledByNative = false;
}
if (DEBUG) {
Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+ " final map: " + mMap);
}
}
好了,今天的学习先就此告一段落。“goodNight my stranger”
本文地址:https://blog.csdn.net/github_28948711/article/details/109632730
上一篇: jquery中Ajax请求,get方式与post方式
下一篇: 2020-11-11