2011-08-31 12 views
30

He creado un GalleryView e ImageView que muestra la imagen más grande cuando se hace clic en un elemento en la galería. He utilizado el siguiente código para implementar el ImageAdapter:cuál es el uso del método recycle() en TypedArray

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

Cuando quité la declaración a.recycle() no hay cambio y la aplicación está funcionando normalmente como antes, sino en todas partes he leído que es obligatorio para reciclar el TypedArray. Cuando no hay cambios en la forma en que se ejecuta mi aplicación, ¿cuál es el uso del método recycle()?

¿Puede alguien explicarme en detalle? Gracias.

Respuesta

25

El punto es similar a la idea de borrar un puntero en un lenguaje C (si está familiarizado con eso). Se usa para hacer que los datos asociados con "a" estén listos para la recolección de basura, de modo que la memoria/datos no se vinculen ineficientemente con "a" cuando no es necesario. Leer más here. Es importante tener en cuenta que esto no es realmente necesario a menos que realmente esté reutilizando "a". GC debería borrar automáticamente estos datos por usted si el objeto no se usa nuevamente. La razón por la cual un TypedArray es diferente, sin embargo, se debe a que TypedArray tiene otros datos internos que deben devolverse (conocidos como StyledAttributes) al TypedArray para su reutilización posterior. Lea sobre eso here.

+2

Nota complementaria: GC significa "recolección de basura". – Vinay

+3

No entiendo. El último enlace hace que parezca que llamar a recycle() permite que se reutilice alguna matriz interna. ¿Esto no significa que evita que la matriz se censure?¿Por qué dices que hace que los datos asociados con "a" estén listos para GC? – gsingh2011

+0

@ gsingh2011 le permite "ser reutilizado por un llamante posterior". Es cierto que la redacción de la documentación es un poco incómoda, pero lo que están consiguiendo es que la memoria asociada con el 'TypedArray' puede ser reutilizada por un llamante posterior (no la instancia en sí, ya que lo entiende dentro de los límites de su programa) Es por eso que la documentación también dice: "Después de llamar a esta función, no debe volver a tocar la matriz tipada". – Vinay

5

recycle() hace que la memoria asignada se devuelva al grupo disponible inmediatamente y no se mantendrá hasta la recolección de elementos no utilizados. Este método también está disponible para Bitmap.

0

reciclar significa básicamente ... liberar/borrar todos los datos asociados con el recurso correspondiente. En Android podemos encontrar reciclaje para Bitmap y TypedArray.

Si comprueba ambos archivos fuente, entonces puede encontrar una variable booleana "mReciclado" que es "falsa" (valor predeterminado). Se asigna a "verdadero" cuando se llama reciclado.

Entonces, si comprueba ese método (método de reciclaje en ambas clases), entonces podemos observar que están borrando todos los valores.

Para referencia aquí están los métodos.

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

esta línea

mResources.mTypedArrayPool.release(this); 

dará a conocer el TypedArray del SunchronisedPool cuyo valor predeterminado es 5. Por lo que no debería usar el mismo Array tipeado nuevamente cuando se borre.

Una vez que "mRecycled" de TypedArray es verdadero, al obtener sus propiedades lanzará RuntimeException diciendo "No se pueden realizar llamadas a una instancia reciclada".

comportamiento simliar en el caso de Bitmap también. Espero que ayude.

Cuestiones relacionadas