当前位置: 移动技术网 > 科技>操作系统>windows > 探索下Intent.getxxxExtra()是否需要捕获异常

探索下Intent.getxxxExtra()是否需要捕获异常

2020年11月11日  | 移动技术网科技  | 我要评论
偷个懒:共同探索下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

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网