Aperçu des Thread et
Processus sur Android
Processus Android
• Le système Android démarre un nouveau processus Linux pour
l'application avec un seul thread d'exécution.
• Par défaut, tous les composants d’une même application
s’exécutent dans le même processus et le même thread (appelé
main thread).
• Lorsqu'un composant d'application démarre et qu'aucun autre
composant n'est en cours d'exécution, le système Android
démarre un nouveau processus Linux pour l'application avec un
seul thread d'exécution.
• Cependant, on peut faire en sorte que différents composants de
votre application s'exécutent dans des processus distincts et on
peut créer des threads supplémentaires pour n'importe quel
processus.
Processus Android
• Par défaut, tous les composants d'une application s'exécutent
dans le même processus, et la plupart des applications ne
changent pas cela.
• Cependant, si on constate qu’on doit contrôler à quel processus
appartient un certain composant, on peut le faire dans le fichier
manifeste.
• L'entrée du manifeste pour chaque type d'élément de
composant (<activity>, <service>, <receiver> et <provider>)
prend en charge un attribut android:process qui peut spécifier
un processus dans lequel le composant s'exécute.
<activity
android:name=".SettingsActivity"
android:process=":setting"
android:label="@string/title_activity_settings">
</activity>
• Si on ajoute android:process=":setting" à notre activité par
défaut puis on démarre une autre activité, notre
application aura 2 processus :
[Link].tp1:setting
[Link].tp1
• L'activité principal démarrera sur le processus par défaut,
car elle n'a pas de balise de processus définie.
• On peut définir cet attribut pour que chaque composant
s'exécute dans son propre processus ou pour que certains
composants partagent un processus tandis que d'autres
ne le font pas.
• Le Tag “android:process” peut etre appliqué sur 4
composants android :
• Activity , Service , Receiver , Provider , et aussi sur le tag
Application
• Lorsqu'ils sont appliqués sur le tag Application, tous les
composants de l'application héritent également de
android:process à moins qu'ils ne soient surchargés
(override) par leur propre balise android:process.
Quand dois-je rendre mon application multi-processus ?
• Il y a 2 raisons pour créer une application multi-processus :
1. L’ application comporte des actions distinctes qui doivent être
exécutées indépendamment.
• L'exemple courant est qu'une application de lecture de musique aurait le
processus par défaut qui gère l'interface utilisateur et un autre processus
pour gérer la lecture de musique.
2. L’ application rencontre des contraintes de mémoire. Android limite
l'utilisation de la RAM par processus.
• On peut ainsi augmenter la limite totale de RAM de cette application en
exécutant plusieurs processus.
• Cependant, comme les processus ne partagent pas de mémoire, on ne peut
pas partager de Singleton entre processus.
• Singleton est une classe qui ne permet de créer qu'une seule instance d'elle-
même et donne généralement un accès simple à cette instance.
Local vs Global process
• Le type de processus dépend de la valeur qu’ on entre dans le
tag de processus.
• Si on commence par deux points (“:”), alors le processus est
local et privé pour notre application (le nom complet du
processus serait applicationId:processName).
• Si on commence par une lettre minuscule, il s'agit d'un
processus global.
• Un processus global peut être partagé entre les applications.
• Souvent, une bibliothèque s'exécute sur un processus global
afin que plusieurs applications puissent partager le processus
afin de réduire l'utilisation de la mémoire.
Thread Android
• Thread est l’un des concepts importants d’Android.
• Thread est un sous-processus léger qui nous permet d'effectuer
des opérations en arrière-plan sans interrompre l'interface
utilisateur(UI).
• Lorsqu'une application est lancée, elle crée un thread unique
dans lequel tous les composants de l'application s'exécuteront
par défaut.
• Le thread créé par le système d’exécution est appelé thread
principal.
• Le rôle principal du thread principal est de gérer l’interface
utilisateur en termes de gestion des événements et
d’interaction avec les vues de l’interface utilisateur.
• Si une tâche s’exécute sur le thread principal et prend beaucoup de
temps, elle arrêtera les autres tâches jusqu'à ce qu'elle soit terminée,
• Cela peut entraîner l'affichage d'un avertissement «L'application ne
répond pas» à l'utilisateur par le système d’exploitation.
• Donc, on a besoin de threads différents pour ces tâches et pour
certaines autres tâches.
• Sous Android, tous les composants de thread sont classés
en deux catégories de base :
1. Threads attachés à une activité/fragment : ces
threads sont liés au cycle de vie de l'activité/fragment et
se terminent dès que l'activité/fragment est détruit.
- AsyncTask - Loaders
2. Threads qui ne sont attachés à aucune
activité/fragment : ces threads peuvent continuer à
s'exécuter au-delà de la durée de vie de l'activité/du
fragment à partir duquel ils ont été générés.
- Worker thread - ServiceIntent - Service
Pourquoi avons-nous besoin d’une
programmation asynchrone sur Android ?
• Le système Android, par défaut, exécute le pipeline de rendu de l'interface
utilisateur, les composants de base (activité, fragment, service,…), la
gestion des rappels du cycle de vie et le traitement des interactions de
l'interface utilisateur sur un seul thread, parfois appelé UI thread ou thread
principal,
• Le thread principal gère son travail de manière séquentielle en collectant
son travail à partir d'une file d'attente de tâches (Message Queue) qui
sont mises en file d'attente pour être traitées par un composant
d'application particulier.
• Lorsqu'une unité de travail, telle qu'une opération d'E/S, prend un certain
temps, elle bloque et empêche le thread principal de gérer les tâches
suivantes en attente de traitement dans la file d'attente du thread
principal.
Pourquoi avons-nous besoin d’une
programmation asynchrone sur Android ?
• La plupart des appareils Android actualisent l'écran 60
fois par seconde, donc toutes les 16 ms (1 s/60 images),
une tâche de rendu de l'interface utilisateur (UI
Rendering) doit être traitée par le thread principal afin de
dessiner et de mettre à jour l'écran de l'appareil.
• Le taux de rafraîchissement (Refresh
Rate) mesure la période de temps entre
les mises à jour de l’affichage d’un
téléphone. c'est a dire, à quelle
fréquence et à quelle vitesse le contenu à
l’écran est actualisé.
• Mesuré en Hertz (Hz), le taux de
rafraîchissement compte le nombre de
fois où l'écran se rafraîchit complètement
chaque seconde.
• Un écran à 60 Hz s'actualise 60 fois par
seconde, 90 Hz correspond à 90 fois par
seconde, 120 Hz correspond à 120 fois
par seconde.
• Lorsqu'une opération de longue durée empêche le
thread principal d'exécuter le rendu d'image à temps, le
dessin d'image actuel est différé ou certains dessins
d'image sont manqués, générant un problème
d'interface utilisateur (UI glitch) perceptible pour
l'utilisateur.
• Une opération typique de longue durée pourrait être :
• Network data communication
• File Upload or Backup
• Reading or writing of files to the file system
• Shared Preferences Files
• File Cache Access
• Internal Database reading or writing
• Camera, Image, Video, Binary file processing.
• Exemple, lorsqu'une opération de blocage domine le thread
principal pendant plus de 2 frame rendering.
• 2 UI frames sont supprimés et 1 UI Rendering frame a été différée car
l’opération de blocage a pris environ 35 ms pour se terminer.
• Lorsque l'opération de longue durée ne se termine pas dans les 5
secondes, le système affiche une boîte de dialogue « L'application ne
répond pas » (ANR) à l'utilisateur, lui donnant la possibilité de fermer
l'application.
• Afin d'exécuter des opérations d'E/S gourmandes en calcul ou
bloquantes sans supprimer une UI frame, générer des UI glitches
ou dégrader la réactivité de l'application,
• On doit confier l'exécution de la tâche à un thread d'arrière-plan,
avec moins de priorité, qui s'exécute simultanément et de manière
asynchrone dans une ligne d'exécution indépendante.