TypedArray中的recycle()方法有什么用途?

50

我创建了一个GalleryViewImageView,当在图库中点击一个项目时,它会显示更大的图像。我使用以下代码实现了ImageAdapter

public ImageAdapter(Context c)
{
    context = c;
    TypedArray a = obtainStyledAttributes(R.styleable.gallery1);
    itemBackground = a.getResourceId(R.styleable.gallery1_android_galleryItemBackground, 0);    
    a.recycle();    
}

当我删除语句a.recycle()时,没有变化,应用程序运行正常,但是我读到的每个地方都说必须回收typedArray。如果我的应用程序运行方式没有改变,那么recycle()方法有什么用处?

4个回答

52
这一点类似于在C语言中清除指针(如果您熟悉的话)。它用于使与 a 相关的数据准备好进行垃圾回收,以便当不需要与 a 相关联时,内存/数据不会低效地绑定到 a。更多信息请在此处阅读。
需要注意的是,这并不是真正必需的,除非您实际上要重复使用 "a"。如果对象不再使用,则 GC 应自动为您清除此数据。然而,TypedArray 不同的原因是,TypedArray 具有其他必须返回的内部数据(称为StyledAttributes),以供稍后重用。请在此处了解详情。

2
附注:GC代表“垃圾收集”。 - Vinay
3
我不明白。最后一个链接似乎暗示调用recycle()会使某些内部数组得以重复利用。这难道不意味着它阻止了该数组被垃圾回收吗?为什么你说它会使与“a”相关联的数据准备好被垃圾回收呢? - gsgx
1
@gsingh2011它允许“稍后的调用者重新使用它”。诚然,文档措辞有些笨拙,但他们想表达的是与TypedArray相关联的内存可以被稍后的调用者(而不是程序内部你所理解的实例本身)重新使用。这就是为什么文档还说“调用此函数后,您绝不能再次触摸类型化数组。”。 - Vinay

12

recycle()方法会立即将分配的内存返回到可用池中,不会一直保留到垃圾回收。该方法也适用于Bitmap


0

由于它的使用已经结束[在初始化本地属性之后],因此我们将其回收到资源池中

简单易懂


0

回收基本上是指..释放与相应资源相关联的所有数据。在Android中,我们可以找到Bitmap和TypedArray的回收。

如果您检查这两个源文件,那么您可以找到一个布尔变量“mRecycled”,它是“false”(默认值)。当调用回收时,它被分配为“true”。

因此,现在如果您检查这个方法(在两个类中的回收方法),那么您会发现它们清除了所有值。

参考以下方法。

Bitmap.java:

    public void recycle() {
    if (!mRecycled && mNativePtr != 0) {
        if (nativeRecycle(mNativePtr)) {
            // return value indicates whether native pixel object was actually recycled.
            // false indicates that it is still in use at the native level and these
            // objects should not be collected now. They will be collected later when the
            // Bitmap itself is collected.
            mBuffer = null;
            mNinePatchChunk = null;
        }
        mRecycled = true;
    }
}

TypedArray.java

    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);
}

这一行

mResources.mTypedArrayPool.release(this);

将默认值为5的typedArray从同步池中释放。因此,您不应再次使用相同的typedArray,因为它已被清除。

一旦TypedArray的“mRecycled”为true,则在获取其属性时会抛出RuntimeException,指示“无法对已回收的实例进行调用!”。

Bitmap行为类似。希望能够帮到您。


有人能描述一下这里回收的设计目的吗?我通常认为“池”是一种节约资源的方式(例如最大内存占用或处理时间),并让进程等待而不是按需创建新对象,其中峰值需求可能非常大或初始化新对象很昂贵。这里的TypedArray的解释似乎表明在回收时有大量的垃圾收集正在进行,那么整个数组回收起来是否很昂贵呢?我试图更好地了解回收模式。 - sb4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接