Lorsque vous appuyez sur « Installer » sur un fichier APK ou téléchargez une application depuis le Play Store, une séquence complexe d'opérations commence en coulisses. Ce qui semble être une simple barre de progression représente en réalité des dizaines d'étapes impliquant l'analyse des packages, la vérification cryptographique, la gestion des autorisations, l'extraction de fichiers et l'optimisation du code. Comprendre ce processus permet d'expliquer pourquoi les installations échouent parfois et ce que vous pouvez faire pour y remédier.
Dans cet article, nous passerons en revue chaque étape majeure du pipeline d'installation d'Android, depuis le moment où le système reçoit un APK jusqu'au moment où l'application est prête à être lancée.
Étape 1 : lancement de l'installation
Le processus d'installation commence différemment selon la source :
- Play Store : L'application Play Store télécharge l'APK (ou les APK fractionnés) et appelle le programme d'installation du package du système avec des privilèges spéciaux qui contournent certaines confirmations de l'utilisateur.
- Chargement latéral : Lorsque vous ouvrez un fichier APK, Android lance l'activité d'installation du package. Sur Android 8.0 et versions ultérieures, l'application qui installe doit disposer de l'autorisation « Installer des applications inconnues » pour sa source spécifique.
- BAD : La commande adb install communique directement avec le service de gestion de packages via USB, en contournant entièrement le programme d'installation graphique.
Quelle que soit la source, toutes les installations finissent par accéder au même service système : le PackageManagerService (PMS). Il s'agit de l'autorité centrale pour toutes les opérations sur les packages sur Android.
Étape 2 : analyse des packages
Avant toute chose, le système doit comprendre ce qu’il s’apprête à installer. Le PackageManagerService appelle le PackageParser pour lire le fichier APK et extraire ses métadonnées.
L'analyseur lit le fichier AndroidManifest.xml à partir de l'APK. Ce fichier XML binaire contient des informations critiques :
- Nom du paquet : L'identifiant unique de l'application (par exemple, com.example.myapp)
- Code et nom de la version : Utilisé pour déterminer s'il s'agit d'une mise à niveau ou d'une nouvelle installation
- Versions minimale et cible du SDK : Détermine la compatibilité avec l'appareil
- Autorisations déclarées : Les autorisations demandées par l'application et les autorisations personnalisées qu'elle définit
- Composants : Activités, services, récepteurs de diffusion et fournisseurs de contenu enregistrés par l'application
- Caractéristiques matérielles et logicielles : Exigences telles que l'appareil photo, le GPS ou les versions spécifiques d'OpenGL
Si le manifeste est mal formé ou si la structure APK n'est pas valide, l'installation échoue à ce stade avec un message « Erreur d'analyse ». C’est l’une des raisons les plus courantes pour lesquelles les APK téléchargés ne parviennent pas à s’installer.
Étape 3 : Vérifications de compatibilité
Une fois le manifeste analysé, le système effectue une série de vérifications de compatibilité :
- Version du SDK : Si le niveau minSdkVersion de l'application est supérieur au niveau API de l'appareil, l'installation est rejetée.
- Compatibilité ABI : Si l'APK contient des bibliothèques natives, le système vérifie si elles correspondent à l'architecture CPU de l'appareil. Un APK contenant uniquement les bibliothèques armeabi-v7a ne sera pas installé sur un appareil x86 uniquement.
- Fonctionnalités requises : Si l'application déclare les fonctionnalités matérielles requises (comme android.hardware.telephony), le système vérifie que l'appareil les prend en charge.
- Stockage disponible : Le système vérifie s'il y a suffisamment d'espace libre pour installer l'application, y compris de l'espace pour les bibliothèques natives extraites et les fichiers DEX optimisés.
Étape 4 : Vérification de la signature
Il s’agit de l’une des étapes les plus critiques du processus d’installation. Android vérifie la signature cryptographique de l'APK pour garantir son intégrité et son authenticité.
Le processus de vérification dépend des schémas de signature présents :
Signature V1 (signature JAR)
Le système vérifie dans le répertoire META-INF/ les fichiers de signature (.SF, .RSA ou .DSA). Chaque fichier de l'APK est vérifié par rapport aux résumés répertoriés dans le manifeste. C'est lent car chaque fichier doit être haché individuellement.
Signature V2 (schéma de signature APK v2)
Introduit dans Android 7.0, ce schéma signe l’intégralité de l’APK en tant que blob binaire. Le bloc de signature est inséré entre le répertoire central ZIP et l'enregistrement de fin de répertoire central. La vérification est beaucoup plus rapide car elle opère sur les octets bruts sans avoir besoin de décompresser les entrées individuelles.
Signature V3 (rotation des touches)
Disponible à partir d'Android 9.0, la V3 étend la V2 avec la prise en charge de la rotation des clés. Il comprend une structure de preuve de rotation qui relie les anciennes et les nouvelles clés de signature, permettant aux développeurs de modifier leur clé de signature tout en conservant la compatibilité des mises à jour.
Signature V4 (incrémentale)
Android 11 a introduit la V4 pour les installations incrémentielles. Il fournit une signature basée sur une arborescence Merkle qui permet la vérification des blocs individuels lors de leur diffusion vers l'appareil.
Si la vérification de la signature échoue pour une raison quelconque, l'installation est immédiatement interrompue. Vous pouvez vérifier la signature d'un APK avant l'installation à l'aide de notre Outil de vérification APK.
Mettre à jour la correspondance de signature
Si une application portant le même nom de package est déjà installée, le système effectue une vérification supplémentaire : le certificat de signature du nouvel APK doit correspondre au certificat de l'installation existante. Cela empêche une partie malveillante de remplacer une application légitime par une version falsifiée. Si les signatures ne correspondent pas, vous verrez l'erreur « Application non installée : le package est en conflit avec un package existant du même nom ».
Étape 5 : Confirmation de l'utilisateur
Pour les installations téléchargées, le système affiche une boîte de dialogue de confirmation d'installation affichant :
- Le nom et l'icône de l'application (extraits des ressources de l'APK)
- Autorisations demandées par l'application (sur les anciennes versions d'Android)
- Qu'il s'agisse d'une nouvelle installation ou d'une mise à jour
- Tout avertissement concernant la source de l'application ou les risques potentiels
Sur Android 12 et versions ultérieures, l'écran de confirmation est plus simple puisque les autorisations d'exécution sont accordées individuellement lorsque l'application en a besoin pour la première fois, plutôt qu'au moment de l'installation.
Étape 6 : Extraction et placement de fichiers
Une fois que l'utilisateur confirme (ou automatiquement pour les installations du Play Store), le système commence à extraire et à placer les fichiers :
Stockage APK
Le fichier APK lui-même est copié sur /data/app/[package-name]-[random]/base.apk. Pour les installations APK fractionnées, des fichiers supplémentaires tels que split_config.arm64_v8a.apk sont placés à côté de l’APK de base. L'APK d'origine dans le dossier Téléchargements n'est ni modifié ni supprimé.
Extraction de bibliothèque native
Si l'APK contient des bibliothèques natives (dans le répertoire lib/, elles sont extraites vers /data/app/[package-name]-[random]/lib/[abi]/). Sur les versions Android plus récentes, les applications peuvent choisir de conserver les bibliothèques natives compressées dans l'APK et de les charger directement à l'aide de android:extractNativeLibs="false", ce qui permet d'économiser de l'espace de stockage.
Création d'un répertoire de données
Le système crée le répertoire de données privé de l'application sur /data/data/[package-name]/ (ou /data/user/0/[package-name]/ sur les appareils multi-utilisateurs). Ce répertoire appartient à un UID Linux unique attribué à l'application, garantissant qu'aucune autre application ne peut y accéder sans les privilèges root.
Étape 7 : Optimisation DEX
Cette étape est celle où Android transforme le bytecode de l'application dans un format optimisé pour le matériel spécifique de l'appareil. Le processus a considérablement évolué au cours de l'histoire d'Android :
L'ère Dalvik (Android 4.4 et versions antérieures)
La machine virtuelle Dalvik d'origine utilisait la compilation Just-In-Time (JIT). Lors de l'installation, le fichier classes.dex a été optimisé dans un fichier ODEX contenant un bytecode vérifié et optimisé. C'était relativement rapide, mais cela signifiait que l'application fonctionnait plus lentement au moment de l'exécution puisque la plupart du code était encore interprété.
ART avec AOT (Android 5.0 à 6.0)
Android Runtime (ART) a remplacé Dalvik et a introduit la compilation Ahead-Of-Time (AOT). Lors de l'installation, l'intégralité du bytecode DEX a été compilée en code machine natif. Cela a rendu les applications plus rapides, mais a considérablement augmenté le temps d'installation et l'utilisation du stockage. Certaines applications ont mis plusieurs minutes à s'installer.
Compilation guidée par profil (Android 7.0+)
Android moderne utilise une approche hybride. Lors de l'installation, seuls les chemins de démarrage critiques sont compilés. Lorsque l'utilisateur exécute l'application, le système collecte des profils d'exécution identifiant les chemins de code fréquemment utilisés. Pendant la maintenance inactive (généralement pendant la charge pendant la nuit), le système compile ces chemins chauds en code natif. Cela équilibre la vitesse d’installation, l’utilisation du stockage et les performances d’exécution.
Le code compilé est stocké dans /data/dalvik-cache/ ou à côté de l'APK sous forme de fichiers .odex, .vdex et .art. Le fichier .vdex contient du code DEX vérifié, le fichier .odex contient du code natif compilé et le fichier .art contient des images de tas pré-initialisées pour un démarrage plus rapide.
Étape 8 : Enregistrement des autorisations
Le PackageManagerService enregistre les autorisations et les composants déclarés de l'application auprès du système :
- Les Autorisations au moment de l'installation (comme INTERNET ou VIBRATE sont automatiquement accordés sans interaction de l'utilisateur).
- Les Autorisations d'exécution (comme CAMERA ou LOCATION sont enregistrés mais ne sont pas accordés). L'application doit les demander au moment de l'exécution.
- Les Filtres d'intention sont enregistrés afin que le système sache quelles applications peuvent gérer quelles actions (comme ouvrir une URL ou partager du contenu).
- Les Fournisseurs de contenu sont enregistrés auprès de leurs autorités afin que d'autres applications puissent les interroger.
Étape 9 : Intégration du système
Les dernières étapes intègrent l'application dans le système Android :
- Mise à jour de la base de données des packages : La base de données de packages du système (/data/system/packages.xml est mise à jour avec les informations de la nouvelle application, y compris son UID attribué, ses autorisations et ses déclarations de composants).
- Notification du lanceur : Le lanceur de l'écran d'accueil est informé de la nouvelle application afin qu'il puisse afficher l'icône de l'application.
- Diffuser: Le système envoie une diffusion PACKAGE_ADDED, permettant à d'autres applications de réagir à la nouvelle installation (par exemple, des applications de sauvegarde peuvent planifier une sauvegarde).
- Contexte SELinux : Les fichiers de l'application sont étiquetés avec le contexte de sécurité SELinux approprié en fonction de la version du SDK cible et des autorisations déclarées.
Pourquoi les installations échouent
Comprendre le pipeline d'installation permet de diagnostiquer les pannes courantes :
- "Erreur d'analyse" : L’APK est corrompu, incomplet ou possède un manifeste mal formé. Cela se produit souvent avec des téléchargements incomplets ou des fichiers mal convertis.
- "Application non installée" (incompatibilité de signature) : Vous essayez de mettre à jour une application avec un APK signé par une clé différente. Vous devez d'abord désinstaller la version existante.
- "Stockage insuffisant" : Espace insuffisant pour l'APK, les bibliothèques extraites et la sortie d'optimisation DEX. L’espace réel nécessaire est généralement 2 à 3 fois la taille de l’APK.
- "Le package est en conflit avec un package existant" : Même nom de package mais signature différente. Courant lors du basculement entre le Play Store et les versions téléchargées.
- Rétrogradation de version bloquée : Par défaut, Android empêche l'installation d'une ancienne version sur une version plus récente. ADB peut contourner cela avec la commande adb install -d.
Installation fractionnée de l'APK
Lors de l’installation d’APK fractionnés (à partir d’App Bundles), le processus est légèrement différent. Le système utilise une API installation basée sur une session :
- Une nouvelle session d'installation est créée
- Chaque APK fractionné est écrit dans la session
- La session est validée, déclenchant le pipeline de vérification complet
- Toutes les divisions doivent avoir des noms de package, des codes de version et des certificats de signature correspondants
Il s'agit du mécanisme utilisé par les installateurs XAPK et des outils comme notre Fusion d'APKS vers APK pour gérer les installations multi-fichiers.
Installation via BAD
Lorsque vous utilisez adb install, le processus contourne le programme d'installation graphique mais suit le même pipeline interne. ADB communique avec le service du gestionnaire de packages via une connexion socket. Il prend en charge des indicateurs supplémentaires qui ne sont pas disponibles via l'interface graphique :
- -r : remplacer l'application existante (autoriser la réinstallation)
- -d : Autoriser la rétrogradation de version
- -g : accordez immédiatement toutes les autorisations d'exécution
- -t : Autoriser l'installation d'APK de test uniquement
- --install-multiple : installez des APK divisés en une seule session
Que se passe-t-il lors de la désinstallation
Pour être complet, voici ce qui se passe lorsqu'une application est supprimée :
- Les processus de l'application sont tués
- L'APK et les bibliothèques extraites sont supprimés de /data/app/
- Le répertoire de données privées de l'application est supprimé (sauf si l'utilisateur a choisi de conserver les données)
- Les fichiers de cache DEX compilés sont supprimés
- La base de données des packages est mise à jour
- Une diffusion PACKAGE_REMOVED est envoyée
- Le lanceur supprime l'icône de l'application
Notez que les fichiers spécifiques aux applications sur le stockage externe (/Android/data/[package]/ et /Android/obb/[package]/ sont également supprimés sur Android 10 et versions ultérieures, grâce à l'application du stockage étendu).
Pourquoi comprendre PackageManager permet de gagner du temps de débogage
Le processus d'installation d'Android est une séquence soigneusement orchestrée de contrôles de sécurité, d'opérations sur les fichiers et d'intégrations système. Chaque étape répond à un objectif, depuis la protection des utilisateurs contre les applications falsifiées jusqu'à l'optimisation des performances du matériel spécifique. Lorsque les installations échouent, l’erreur pointe généralement vers une étape spécifique de ce pipeline, et comprendre le processus vous aide à diagnostiquer et à résoudre rapidement les problèmes.
L'installation à partir du Play Store, le chargement manuel d'un APK et la diffusion d'une version avec ADB passent par le même pipeline sous-jacent, celui qui garantit que chaque application sur votre appareil a été vérifiée, placée correctement et optimisée pour votre matériel.