2011-10-05 15 views
9

Tengo una aplicación para Android con muchas animaciones.Imágenes agregadas a AnimationDrawable memoria de pérdida programada

Cuando mediante programación crear animaciones (utilizando AnimationDrawable) el objeto no Java (como aparece en la pestaña DDMS Montón) crece con cada nueva animación me carga y nunca se contrae de nuevo, incluso después de mis animaciones son liberados.

que tienen una sola referencia a cada objeto AnimationDrawable de un objeto contenedor que escribí y que verifica este objeto se libera reemplazando el método finalize y asegurarse de que se llama.

Eventualmente, Android detiene la carga de imágenes e imprime errores "sin memoria" en el registro.

Lo interesante es que esto ocurre solo en algunos dispositivos (Motorola Xoom, Sony Experia) y no en otros (como el Galaxy S).

Este problema no es específico de Honeycomb o pre-Honeycomb como se puede ver en los ejemplos del dispositivo que di.

Algunas de las cosas que intenté:

  1. Llamada de reciclaje en cada una de las tramas después que haya terminado con la animación actual, pero no parece ayudar.
  2. Asignación nula al objeto AnimationDrawble
  3. Asegurarse de que no hay ninguna variable estática relacionada con la clase que contiene la referencia a la animación dibujable
  4. Asegúrese de que el problema desaparece una vez que comento hacia fuera myAnimation.addFrame(...)
+0

¿Podría publicar la RAM total de cada dispositivo? Además, ¿de qué tipo de animación estás hablando? ¿Podría publicar un ejemplo del código de inicialización? –

+0

La XOOM tiene 1GB de RAM y estoy usando la bandera de "gran montón" en el manifiesto, la Galaxy S tiene 512MB – Gu1234

+0

Esa cosa 'myAnimation.addFrame' me hizo sospechar que puede que no esté usando esto como está previsto. Por favor, publique un pequeño fragmento. –

Respuesta

0

Esta no es una respuesta exacta, sino más bien una sugerencia útil para encontrar dónde se produce la fuga exacta. Realice un montón de vueltas después de esperar que se recupere su memoria y vea por qué los objetos que cree que deberían estar muertos siguen vivos.

Asegúrese de obtener la herramienta del analizador de memoria para eclipse. (http://www.eclipse.org/mat/)

0

Podría haber dos razones posibles, primero en el momento de crear el mapa de bits y segundo cuando está convirtiendo el mapa de bits en el mapa de bits extraíble. Como puedo ver en tu comentario (new BitmapDrawable(currentFrameBitmap) ahora este método se deprecia mejor para usar BitmapDrawable(getResources(),currentFrameBitmap) Sin la referencia de Recursos, el mapa de bits puede no mostrarse correctamente, incluso cuando se escala correctamente. Para cargar el mapa de bits de manera eficiente, puede escalarlo correctamente.

public class BitmapDecoderHelper { 
private Context context; 
public BitmapDecoderHelper(Context context){ 
    this.context = context; 
} 
public int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) { 
// Raw height and width of image 
final int height = options.outHeight; 
final int width = options.outWidth; 
int inSampleSize = 1; 
Log.d("height reqheight width reqwidth", height+"//"+reqHeight+"//"+width+"///"+reqWidth); 
if (height > reqHeight || width > reqWidth) { 
    if (width > height) { 
     inSampleSize = Math.round((float)height/(float)reqHeight); 
    } else { 
     inSampleSize = Math.round((float)width/(float)reqWidth); 
    } 
} 
return inSampleSize; 
} 
public Bitmap decodeSampledBitmapFromResource(String filePath, 
     int reqWidth, int reqHeight) { 

    // First decode with inJustDecodeBounds=true to check dimensions 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 

    BitmapFactory.decodeFile(filePath, options); 
    // Calculate inSampleSize 
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 
    Log.d("options sample size", options.inSampleSize+"///"); 
    // Decode bitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 
    // out of memory occured easily need to catch and test the things. 
    return BitmapFactory.decodeFile(filePath, options); 
} 
public int getPixels(int dimensions){ 
    Resources r = context.getResources(); 
    int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dimensions, r.getDisplayMetrics()); 
    return px; 
} 
public String getFilePath(Uri selectedImage){ 
    String[] filePathColumn = {MediaStore.Images.Media.DATA}; 
    Cursor cursor = context.getContentResolver().query(selectedImage, filePathColumn, null, null, null); 
    cursor.moveToFirst(); 
    int columnIndex = cursor.getColumnIndex(filePathColumn[0]); 
    String filePath = cursor.getString(columnIndex); 
    cursor.close(); 
    return filePath; 
} 

}