• 30 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 1/13/20

Explorez le cycle de vie des activités

Log in or subscribe for free to enjoy all this course has to offer!

Dans cette partie, on va s’intéresser au cycle de vie d’une activité. Cela va permettre de comprendre comment est exécutée une application par le système d’exploitation et comment sont gérées les tâches qui sont gourmandes en temps et qui nécessitent l’utilisation de tâches asynchrones.

Avant de parler du cycle de vie d'une application Android, il faut se familiariser avec la gestion des processus. Celle-ci est particulière, et diffère d’un Linux classique, notamment parce qu’il faut économiser au maximum les ressources du téléphone mobile et aussi parce que certaines tâches sont plus prioritaires que d’autres (par exemple l’affichage). Lorsqu’on lance une application, on crée un processus UNIX du point de vue du noyau du système d’exploitation. Ce processus, dans les version antérieures à Marshmallow, était une machine virtuelle Dalvik qui exécute le bytecode de l’application. Dans les versions postérieures, il s’agit d’un binaire compilé à partir du bytecode, embarquant une partie des aspects gérés par une machine virtuelle Java.

Comme vous le savez déjà, une activité possède un certain nombre de méthodes de démarrage et de fin, que l'on peut surcharger:

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i("CIO", "onCreate !");
...
@Override
protected void onRestart() { super.onRestart(); Log.i("CIO", "onRestart !"); }
@Override
protected void onStart() { super.onStart(); Log.i("CIO", "onStart !"); }
@Override
protected void onResume() { super.onResume(); Log.i("CIO", "onResume !"); }
@Override
protected void onPause() { super.onPause(); Log.i("CIO", "onPause !"); }
@Override
protected void onStop() { super.onStop(); Log.i("CIO", "onStop !"); }
@Override
protected void onDestroy() { super.onDestroy(); Log.i("CIO", "onDestroy !"); }
}
}

Quand l’application démarre, et donc sa première activité A, on passe successivement par onCreate()onStart()  et onResume(). Ces trois méthodes permettent de séparer les codes qui initialisent l’activité en fonction de la raison du redémarrage de l’application. En effet, l’application peut avoir été mise en pause à cause d’une autre application (par exemple car une fenêtre popup d’une autre activité B est apparue). Si une autre activité B à recouvre totalement l’activité courante A, on passe par la méthode onStop(). Si l’on relance l’activité A, par exemple avec le bouton back, on  ré-exécute onStart() et onResume().

 

Au pire, si le système d’exploitation demande à récupérer de l’espace mémoire pour exécuter un autre traitement lourd (par exemple jouer une vidéo), alors Android peut tuer une activité qui était stoppée, ce qui provoque le passage paronDestroy(). Dans ce cas, revenir à cette activité stoppée est équivalent à la recréer. Enfin, si l’on sort de la mise en pause de l'activité A, on réexécute onResume().

Si une activité A est mise en pause, mais qu'elle reste visible (par exemple dans le cas d'une popup de petite taille), la méthode onStop()  n'est pas appelée. En effet, il peut être important de ne pas arrêter certaines parties de l'application car l'utilisateur peut encore apercevoir l'application en dessous. Si l'on revient à l'activité A, seule onResume() est appelée et l'activité reprend son exécution normale.

 

Ainsi, on se rend compte que le cycle de vie particulier d'une application impose l'utilisation de plusieurs méthodes : cela permet de gérer la reprise de l’exécution de l’application lorsque celle-ci est interrompue. De même, lorsqu’on quitte l’application, on peut réaliser différentes tâches suivant si l’application est en pause, stoppée ou détruite. Dans ces méthodes, le code doit rester “rapide” pour ne pas ralentir le lancement de l’application ou bien la transition vers une autre.

Enfin, lorsqu'un processus doit être détruit, par exemple pour récupérer de l'espace mémoire, Android utilise une hiérarchie de priorité. Un processus est prioritairement gardé en mémoire dans l’ordre suivant :

  1. Activité en avant plan i.e. affichée, ainsi que ses sous composants (activité en interaction utilisateur, service attaché à cette activité, BroadCastReceiver exécutant onReceive()).

  2. Activité encore visible, qui n'interagit pas avec l'utilisateur mais qui peut influer sur ce que l'on voit à l'écran (activité ayant affiché une boite de dialogue par exemple (onPause() a été appelé), ou service lié à cette activité visible).

  3. Service s’exécutant dans un processus indépendant.

  4. Activité non visible (onStop() a été appelé).

  5. Processus non actif et gardé pour des raisons de cache.

L'intention de Google avec cette hiérarchie, est de favoriser au maximum l'activité qui s'exécute en avant-plan. En effet, cette activité est celle qui est manipulée par l'utilisateur et c'est donc la plus importante ! De plus, comme cette activité est manipulée par l'utilisateur, elle ne doit toujours rester réactive, ce qui impose de soigner la programmation afin de ne pas geler son interface. C'est ce que nous allons creuser dans le chapitre suivant avec l'étude du thread principal.

Example of certificate of achievement
Example of certificate of achievement