Les threads composants une application Android
Date de publication : 22 mars 2010
Par
Davy Leggieri (Page de Davy Leggieri)
Cet article présente les threads d'une application Android.
I. Introduction
II. Les threads d'une application
II-A. L'UI thread
II-B. Le garbage collector
II-C. Le thread "Signal Catcher"
II-D. Les "Binder thread"
III. Création de threads
IV. Conclusion
V. Remerciements
I. Introduction
Vous avez probablement déjà réalisé une application Android sans vous soucier du fonctionnement des threads
dans celle-ci. Cela est valable peut-être pour certains types d'applications, mais il est important
de ne pas négliger cela notamment pour parfaitement contrôler le comportement de votre application.
L'objectif de cet article va être de faire le tour d'horizon des threads créés par une application Android.
Le rôle de chaque thread sera évoqué et nous terminerons par la présentation de la création de threads.
II. Les threads d'une application
Toute application Android est composée d'une multitude de threads. Certaines vous sont complètement inutiles,
d'autres sont plus intéressants et puis il est toujours bon de connaître le fonctionnement global
d'Android.
Je propose de baser notre analyse sur une capture d'écran de la perspective DDMS d'Eclipse. Cette
perspective est ajoutée par le plug-in ADT et est dédiée au débogage d'applications. La partie
de la perspective qui nous intéresse est "l'afficheur des threads d'une application". En sélectionnant
une application au hasard tournant soit sur un Android Virtual Device (AVD), soit sur un téléphone
physique, nous pouvons avoir la liste des threads.

Les threads d'une application
Nous pouvons constater que cette application utilise six threads. Bien entendu, une grande partie de
ces threads ne sont pas créés explicitement par le développeur, certains sont liés à l'utilisation
du langage Java et d'autres sont créés par le système d'exploitation Android lui-même. Nous allons
lister un à un les threads présents sur cette capture d'écran et décrire brièvement le rôle de chacun
d'eux.
-
main : appelé aussi UI Thread, il exécute l'activity ou le service et s'occupe de l'affichage.
-
HeapWork : le thread du garbage collector.
-
JDWP (Java debug Wired Protocol) : thread dédié au débogage (photo prise grâce au débogueur).
-
Signal Catcher : thread dédié à la réception de signaux ("signal" UNIX).
-
Binder Thread #x : threads créés par le système (utiles au bon fonctionnement d'Android).
II-A. L'UI thread
Ce thread est le fil de vie de votre Activity ou Service. Ainsi, les instructions rédigées dans les méthodes
onCreate(), onStart(), OnPause(), onResume(), onStop(), onDestroy() de votre Activity ou
les méthodes onCreate(), onStart(), onStartCommande(), onBind(), onUnbind(), onDestroy()
de votre service sont toutes exécutées dans ce thread.
public class TestActivity extends Activity {
...
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
}
...
}
|
Ce thread est également appelé UI thread car il est responsable de l'affichage et des interactions
avec l'utilisateur. Par exemple, si vous touchez l'écran du doigt, ce thread entre en action et
est averti de votre toucher. Son rôle va être de rediriger cette action aux bons éléments de la
vue.
L'UI thread est le seul thread qui doit modifier l'affichage. Et pour contourner ce problème, nous pouvons
lui soummettre des instructions sous la forme de
Runnable
grâce notamment à la méthode
runOnUiThread() de l'Activity.
 |
Ce thread n'est pas fait pour effectuer des traitements consommateurs en temps. Tout d'abord si
le traitement excède le délai de 5 secondes vous aurez le traditionnel message "application not
responsive". Ensuite, en monopolisant le thread vous ne le laissez pas faire son rôle primaire qui
est de scruter les actions de l'utilisateur et modifier l'affichage.
|
Tous les threads peuvent appeler des méthodes modifiant la vue telles que setText() sur un TextView,
cependant le résultat est garanti uniquement s'il s'agit d'un appel effectué depuis l'UI thread.
II-B. Le garbage collector
Ce thread est la particularité du langage Java, c'est lui qui est chargé d'analyser la mémoire à la recherche
de variables qui ne sont plus référencées par votre code dans le but de supprimer les variables
et objets qui ne sont plus utilisés. Le garbage collector d'Android est assez simpliste puisqu'il
s'agit d'un garbage collector "mark and swipe" et non générationnel comme sur les Java Desktop
actuels. Pour faire son traitement, le garbage collector bloque l'exécution du programme pendant
en moyenne 100ms. Cette contrainte peut parfois être pénible pour l'utilisateur car elle se caractérise
par un gel de l'écran si une animation avait lieu, ou alors une application ne répondant plus du
tout, pendant que le garbage collector effectue son ménage. Il est ainsi important de ne pas instancier
de trop nombreuses variables ou objets dans des boucles critiques. En effet, la multiplication des
allocations peut déclencher un nettoyage de la mémoire par le garbage et donc ralentir l'exécution.
 |
À des fins de test, nous pouvons demander explicitement le nettoyage de la mémoire grâce à l'appel System.gc().
Ce dernier permet de constater le temps que peut prendre un nettoyage de la mémoire et notamment
tester les effets d'une telle action sur votre application.
|
II-C. Le thread "Signal Catcher"
 |
Les informations sur ce thread ne concernent que les curieux, car le développeur lambda n'a jamais recours
à ce thread.
|
Comme son nom l'indique, ce thread réagit à des signaux UNIX et réalise différentes opérations
en fonction du signal reçu. Il peut par exemple stopper l'exécution de tous les autres threads pour
faire une copie de la pile, un "dump stack" et une copie de la pile de la JVM Dalvik. Il peut également
forcer l'exécution du garbage collector. Ceci est une liste non exhaustive de ses actions. Vous
l'aurez compris, son fonctionnement est assez technique et vous n'aurez pas à vous soucier de
l'existence de ce thread.
II-D. Les "Binder thread"
 |
Tout comme précédemment, le développeur n'aura jamais besoin de manipuler ce type de thread.
|
Ces threads sont des réservoirs à thread (threads pool). Ils sont créés par le système Android
dans le but d'optimiser la création de threads notamment par la réutilisation d'anciens threads.
Si on crée beaucoup de threads dans une application, on peut observer le nombre de "Binder thread"
s'accroître. Qu'on se rassure, leur existence n'implique pas une consommation de temps CPU.
III. Création de threads
Dans une grande majorité des cas, l'UI thread permet de réaliser toutes les opérations nécessaires au
fonctionnement de votre application. Cependant, certaines actions sont consommatrices en temps et
peuvent même nécessiter des opérations asynchrones. Dans ce cas précis, il est intéressant
d'envisager la création de threads. Le thread peut, par exemple, se charger de compléter au fur et
à mesure les informations affichées à l'écran. Typiquement, il complète une liste, récupère des informations
d'Internet, consulte la base de données des contacts, etc.
La classe incriminée est
Thread.
Généralement, nous l'instancions en lui donnant un
Runnable qui contient le code qui sera
exécuté par le thread fraîchement créé. L'instanciation de l'objet est la première étape, et la seconde
est l'appel à la méthode
start(). Cette dernière va créer et démarrer l'exécution du thread.
Le thread existera pendant l'exécution du Runnable et mettra fin à ses jours lorsque toutes les instructions
auront été exécutées.
public class testActivity extends Activity {
...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
setContentView(R.layout.main);
new Thread(new Runnable() {
@Override
public void run() {
}
}).start();
}
...
}
|
 |
Pour afficher la liste des contacts, nous pouvons récupérer l'ensemble des noms de ceux-ci et les afficher
immédiatement. Ces actions sont réalisées dans l'Activity, alors que, en parallèle, dans un thread
fraîchement créé nous pouvons récupérer les photos des contacts et les soummettre à l'UI thread pour
qu'il les ajoute à la vue.
|
Le thread créé peut être visualisé sous la perspective DDMS. Il s'agit exactement de la même vue d'Eclipse
que précédemment.

Le nouveau thread visualisé sous DDMS
 |
On peut observer qu'un nouveau "binder thread" a été créé. Et nous pouvons même affirmer que ce "binder
thread" est le créateur du thread nouvellement formé.
|
IV. Conclusion
Nous avons présenté les threads composants une application Android. Plus que le nombre de threads, c'est
le rôle de ceux-ci qu'il est bon de connaître. La plupart ne sont pas manipulés par le développeur
lui-même, mais leurs effets doivent être connus, notamment celui du garbage collector.
V. Remerciements


Copyright © 2010 Davy Leggieri. Aucune reproduction, même partielle, ne peut être faite
de ce site et de l'ensemble de son contenu : textes, documents, images, etc.
sans l'autorisation expresse de l'auteur.
Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 €
de dommages et intérêts.
Cette page est déposée.