【问题标题】:what is the use of recycle() method in TypedArrayTypedArray 中 recycle() 方法的用途是什么
【发布时间】:2011-08-31 05:21: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() 方法的用途是什么?

【问题讨论】:

    标签: android


    【解决方案1】:

    这点类似于在 C 语言中清除指针的想法(如果您熟悉的话)。它用于使与a 关联的数据准备好进行垃圾回收,因此内存/数据在不需要时不会低效地绑定到a。阅读更多here

    重要的是要注意,除非您实际上是在重用“a”,否则这并不是真正必要的。如果对象不再使用,GC 应该会自动为您清除这些数据。但是,TypedArray 不同的原因是,TypedArray 有其他内部数据必须返回(称为StyledAttributes)到TypedArray 以供以后重用。阅读here

    【讨论】:

    • 旁注:GC 代表“垃圾收集”。
    • 我不明白。最后一个链接看起来像是调用 recycle() 允许重用一些内部数组。这不意味着它会阻止数组被 GCed 吗?为什么说它使与“a”关联的数据为 GC 做好了准备?
    • @gsingh2011 它允许它“被以后的调用者重新使用”。诚然,文档的措辞有点尴尬,但他们得到的是与 TypedArray 关联的内存可以被以后的调用者重用(而不是实例本身,因为你在程序的范围内理解它)。这就是为什么文档还说“在调用此函数后,您不能再触摸类型化数组。”。
    【解决方案2】:

    recycle() 导致分配的内存立即返回到可用池中,并且不会一直停留到垃圾回收。此方法也适用于Bitmap

    【讨论】:

      【解决方案3】:

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

      如果您检查两个源文件,那么您可以找到一个布尔变量“mRecycled”,它是“false”(默认值)。调用 recycle 时将其分配为“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 的 SunchronisedPool 中释放 typedArray。 所以你不应该再次使用相同的 typedArray,因为它被清除了。

      一旦 TypedArray 的“mRecycled”为真,那么在获取它的属性时,它会抛出 RuntimeException 说“无法调用回收的实例!”。

      位图的类似行为也是如此。 希望对您有所帮助。

      【讨论】:

      • 有人能在这里描述一下回收的设计目的吗?我通常认为“池”是一种节省资源(例如最大内存占用或处理时间)并让进程等待而不是按需创建新对象的方法,因为峰值需求可能非常大或初始化新对象的成本很高。这里对 TypedArray 的解释似乎表明无论如何回收时都会进行大量垃圾收集,那么回收整个数组的成本是否很高?我正在尝试更好地了解回收模式。
      【解决方案4】:

      由于它的使用已经结束[after initializing our local attributes]所以我们将它回收到资源池中

      简单

      【讨论】:

        猜你喜欢
        • 2018-04-24
        • 2018-03-10
        • 2011-02-03
        • 2011-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-31
        相关资源
        最近更新 更多