2010-03-01 3 views
28

J'ai eu un tas de code dans une activité qui affiche un graphique en cours d'exécution de certaines données externes. Comme le code d'activité devenait sorte de encombrées, je décide d'extraire ce code et créer une classe GraphView:Comment gérer le cycle de vie dans une classe dérivée 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 
    } 
     . 
     . 
     . 
} 

mouvement des choses dans cette nouvelle LinearLayout classe était simple dérivée de. Mais il y avait un code de gestion du cycle de vie associé à la création et à la destruction des timers et des écouteurs d'événements utilisés par ce graphique (je ne voulais pas que cette chose interroge en arrière-plan si l'activité était en pause, par exemple).

Issu d'un milieu MS Windows, je genre d'attendions à Overridable méthodes onCreate() et onDestroy() ou quelque chose de similaire, mais je n'ai rien trouvé de tel dans LinearLayout (ou l'un de ses membres hérités). Le fait de devoir laisser tout ce code d'initialisation dans l'activité, puis de le passer dans la vue, a semblé aller à l'encontre de l'objectif initial d'encapsuler tout ce code dans une vue réutilisable. J'ai fini par ajouter deux méthodes publiques supplémentaires à mon avis: start() et stop(). Je fais ces appels à partir des méthodes onResume() et onPause() de l'activité respectivement.

Cela semble fonctionner, mais j'ai l'impression d'utiliser du ruban adhésif ici. Est-ce que quelqu'un sait comment cela est généralement fait? J'ai l'impression qu'il me manque quelque chose ...

+0

Aujourd'hui, je me suis posé la même question! :) –

Répondre

20

Vous pouvez être en mesure d'obtenir une certaine utilisation de protected void onAttachedToWindow() et protected void onDetachedFromWindow() Je n'ai jamais essayé, mais ils peuvent être appelés à peu près quand vous le souhaitez.

2

Malheureusement, l'objet View n'a pas de méthode de rappel en tant qu'Activité lorsque vous passez du mode Arrière-plan au mode actif. Quoi qu'il en soit, si vous insistez sur une telle approche, je suppose que le plus proche est de placer le code init dans le constructeur et le code de destruction dans un override de finalize(). Cependant, la méthode finalize() est exécutée par le système lorsque l'objet n'est plus référencé, ce qui le rend prêt à être récupéré. Il ne peut pas être appelé du tout si vm se termine. Et je ne recommanderais pas de cette façon. De plus, vous ne voulez pas créer et détruire les objets GraphView encore et encore lorsque votre application passe de pause à reprendre, car les objets de courte durée causent des pertes de mémoire. Vous ne savez jamais quand le gc va libérer de la mémoire pour ces objets, même s'il n'y a aucune référence à eux.

Je pense que votre approrach avec les méthodes start() et stop() est ok, gardez-les simples et propres. Tout ce qu'ils ont à faire est de maintenir les AsyncTasks (ou objets Timer).

(hors sujet en ce qui concerne la façon dont vous gonflez votre point de vue: J'utilise View.inflate() la plupart du temps comme il me sauve quelques lignes de code)

+0

+1 pour View.inflate() –

6

Je n'ai fait une brève expérience avec cela, mais il semble que si vous remplacez onAttachedToWindow et onDetachedFromWindow comme mentionné par CaseyB ci-dessus ainsi primordial

protected void onWindowVisibilityChanged(int visibility)

Il devrait vous donner les informations dont vous avez besoin .

Je suis dans la même situation que vous. Je suis surpris qu'il n'y ait pas de mécanisme de notification pour cela.

Questions connexes