2010-03-01 10 views
28

Tenía un montón de código en una actividad que muestra un gráfico en ejecución de algunos datos externos. Como el código de actividad estaba recibiendo tipo de desordenado, decidí extraer el código y crear una clase GraphView:¿Cómo administrar el ciclo de vida en una clase derivada de ViewGroup?

public class GraphView extends LinearLayout { 
    public GraphView(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     LayoutInflater inflater = (LayoutInflater) 
       context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

     inflater.inflate(R.layout.graph_view, this, true); 
    } 

    public void start() { 
     // Perform initialization (bindings, timers, etc) here 
    } 

    public void stop() { 
     // Unbind, destroy timers, yadda yadda 
    } 
     . 
     . 
     . 
} 

moviendo cosas en esta nueva clase derivada de LinearLayout era simple. Pero había algún código de administración del ciclo de vida asociado con la creación y destrucción de los temporizadores y los detectores de eventos utilizados por este gráfico (no quería que esto sondeara en segundo plano si la actividad se pausó, por ejemplo).

Viniendo de un fondo de MS Windows, que tipo de espera para encontrar reemplazable onCreate() y onDestroy() métodos o algo similar, pero no he encontrado nada parecido en LinearLayout (o cualquiera de sus miembros heredados). Tener que dejar todo este código de inicialización en la Actividad, y luego tener que pasarlo a la vista, parecía que había frustrado el propósito original de encapsular todo este código en una vista reutilizable.

Terminé añadiendo dos métodos públicos adicionales a mi vista: start() y stop(). Realizo estas llamadas desde los métodos onResume() y onPause() de la actividad respectivamente.

Esto parece funcionar, pero parece que estoy usando cinta adhesiva aquí. ¿Alguien sabe cómo esto se hace típicamente? Siento que me falta algo ...

+0

¡Hoy me hice la misma pregunta! :) –

Respuesta

20

Usted puede ser capaz de obtener un cierto uso de anular protected void onAttachedToWindow() y protected void onDetachedFromWindow() Nunca lo he intentado, pero se pueden llamar aproximadamente cuando lo desee.

2

Desafortunadamente, el objeto View no tiene ningún método de devolución de llamada como la actividad cuando se va desde el fondo y el modo activo.

De todos modos, si insiste en tal enfoque, supongo que lo más cercano que puede obtener es poner el código de inicio en el constructor y el código de destrucción en una anulación de finalizar(). Sin embargo, el método finalize() es ejecutado por el sistema cuando ya no se hace referencia al objeto, lo que lo prepara para ser recogido. No se puede invocar si vm sale. Y no lo recomendaría de esta manera.

Además, no desea crear y destruir el (los) objeto (s) GraphView una y otra vez cuando su aplicación pasa de una pausa a la reanudación ya que los objetos efímeros causan pérdidas de memoria. Nunca se sabe cuando el gc liberará memoria para estos objetos, incluso si no hay referencias a ellos.

Creo que su approrach con los métodos start() y stop() están bien, solo mantenlos simples y limpios. Todo lo que tienen que hacer es mantener los AsyncTasks (u objetos Timer).

(fuera de tema en cuanto a la forma en que se inflan sus puntos de vista: Consumo View.inflate() en su mayoría, ya que me salva de unas pocas líneas de código)

+0

+1 para View.inflate() –

6

Sólo he hecho un breve experimento con esto, pero parece que si se reemplaza onAttachedToWindow y onDetachedFromWindow como se mencionó anteriormente por CaseyB junto con primordial

protected void onWindowVisibilityChanged(int visibility)

Debe darle la información que necesita .

Me encuentro con la misma situación que tú. Me sorprende que no haya un mecanismo de notificación para esto.

Cuestiones relacionadas