2012-08-02 11 views
5

Tengo una vista personalizada, que dibuja un montón de cosas incluyendo mapas de bits. Quiero guardar este dibujo en un mapa de bits, de modo que solo necesito dibujar un solo mapa de bits dentro de Draw, en lugar de repetir estas tareas de dibujo y cálculo.¿Dónde desasignar correctamente el mapa de bits en la Vista de Android?

Los mapas de bits deben reciclarse después de que ya no los usemos. No veo en Destroy() ni nada remotamente similar en la clase View. ¿Hay algún método de devolución de llamada que pueda anular para lograr esto?

public void <insert_callback_here>() { 
    cachedBitmap.recycle(); 
} 

No hay animación. Esta es una imagen estática. Hay muchos cálculos realizados para dibujar la imagen, por lo que preferiría hacerlo una vez en onMeasure().

Respuesta

7

Voy a responder la mía aquí. Los métodos adecuados para anular son onDetachedFromWindow. Desasigno mi mapa de bits dentro de onDetachedFromWindow, y los reasigno dentro de onMeasure si el ancho o alto han cambiado.

@Override 
protected void onDetachedFromWindow() { 
    super.onDetachedFromWindow(); 
    if (cachedBitmap != null && !cachedBitmap.isRecycled()) { 
     cachedBitmap.recycle(); 
     cachedBitmap = null; 
     cachedBitmapWidth = -1; 
     cachedBitmapHeight = -1; 
    } 
} 

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    int viewWidth = MeasureSpec.getSize(widthMeasureSpec);; 
    int viewHeight = MeasureSpec.getSize(heightMeasureSpec);; 

    if (cachedBitmapWidth != viewWidth || cachedBitmapHeight != viewHeight) { 
     if (cachedBitmap != null) { 
      cachedBitmap.recycle(); 
     } 
     cachedBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
     cachedBitmapWidth = viewWidth; 
     cachedBitmapHeight = viewHeight; 
     Canvas canvas = new Canvas(cachedBitmap); 
     // do drawings here.. 
    } 

    setMeasuredDimension(viewWidth, viewHeight); 
} 
+0

Esto es exactamente lo que necesitaba. Solo para agregar, también ejecuté un System.gc() después de reciclar los mapas de bits, ya que tenía problemas para tener suficiente memoria. –

+0

Bueno, pero tenga cuidado con las aplicaciones a las que llama finish() desde onCreate(): puede hacer que la memoria se escape de esa manera (consulte https://medium.com/square-corner-blog/android-leak-pattern-subscriptions -in-views-18f0860aa74c). – RhetoricalRuvim

+0

También es importante: es una mala práctica asignar cualquier cosa dentro de Measure() y onDraw(). Por ejemplo, dependiendo de su jerarquía de diseño, onMeasure() se llama como 2 o 3 veces antes de que se determine el tamaño final de la vista. La reasignación dentro de onSizeChanged() sería mejor. – RhetoricalRuvim

Cuestiones relacionadas