1

TypedArray用这段代码测试了回收,希望根据文档得到一个运行时异常,但我没有得到。

回收

在 API 级别 1 中添加
void recycle () 回收 TypedArray,以供以后的调用者重用。调用此函数后,您不得再次触摸类型化数组。

如果 TypedArray 已被回收,则引发 RuntimeException。

    public TimePickerPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.TimePickerPreference, 0, 0);
        initTimePickerPreference(a);
        a.recycle();
    }
    protected void initTimePickerPreference(TypedArray a) {

        if (a != null)
            try {
                setTitle(a.getString(R.styleable.TimePickerPreference_android_title));
                mSummary = a.getString(R.styleable.TimePickerPreference_android_summary);
                mDefaultValue = a.getString(R.styleable.TimePickerPreference_android_defaultValue);
            } finally {
                a.recycle();
            }

    ...
    }

我用 Android Studio 调试器跟踪了代码,它通过了两个a.recycle()调用,而在变量窗格a中没有创建null

我进行这个测试的原因是因为我不是 100% 确定是否可以a.recycle()在与创建位置不同的范围内调用a

我走得更远,重复了回收电话

    public TimePickerPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.TimePickerPreference, 0, 0);
        initTimePickerPreference(a);
        a.recycle();
        a.recycle();
    }
    protected void initTimePickerPreference(TypedArray a) {

        if (a != null)
            try {
                setTitle(a.getString(R.styleable.TimePickerPreference_android_title));
                mSummary = a.getString(R.styleable.TimePickerPreference_android_summary);
                mDefaultValue = a.getString(R.styleable.TimePickerPreference_android_defaultValue);
            } finally {
                a.recycle();
                a.recycle();
            }

    ...
    }

还是没有RunTimeException

这是一个错误吗?
我在带有 Android IceCreamSandwich 版本(API 15)的 AVD 模拟设备上运行它。

4

1 回答 1

1

这是TypedArray#recycle()API 15的实现:

 public void recycle() {
     synchronized (mResources.mTmpValue) {
         TypedArray cached = mResources.mCachedStyledAttributes;
         if (cached == null || cached.mData.length < mData.length) {
             mXml = null;
             mResources.mCachedStyledAttributes = this;
         }
     }
 }

这是API 25 的实现:

public void recycle() {
    if (mRecycled) {
        throw new RuntimeException(toString() + " recycled twice!");
    }
    mRecycled = true;
    // These may have been set by the client.
    mXml = null;
    mTheme = null;
    mAssets = null;
    mResources.mTypedArrayPool.release(this);
}

显然,文档说明了最新 API 的实现,并且您正在使用 API 15 运行您的应用程序。

于 2017-09-28T12:41:56.850 回答