Analyse du packaging d'applications Android

Problème : La taille de l'APK générée par "make project" est d'environ 15M, tandis que l'APK installé sur l'appareil ne fait que 5M.

Une analyse du package décompressé montre que la différence principale se trouve dans le dossier lib.

Pour contrôler le contenu du package, configurez simplement le fichier build.gradle de votre module app :

android {
    defaultConfig {
        ndk {
            abiFilters 'armeabi-v7a'
        }
    }
}

  1. Pourquoi les APK sont-ils fractionnés (package 32 bits, package compatible 32/64 bits, package 64 bits) ? ====================================

Le cœur des appareils Android est le CPU (processeur central). Les architectures CPU courantes incluent ARM et x86, et ces architectures existent en versions 32 bits et 64 bits. Pour s'adapter aux différents appareils Android sur le marché, les APK doivent gérer différentes architectures CPU lors de l'exécution sur le système Android qui appelle les pilotes système. La stratégie des APK pour gérer cette diversité est la fractionnement.

La plupart des téléphones utilisent l'architecture ARM, qui se divise en architecture 32 bits, architecture 64 bits compatible avec 32 bits, et bientôt une architecture 64 bits sans compatibilité 32 bits.

Par conséquent, les packages APK sont divisés en package 32 bits, package compatible 32/64 bits et package 64 bits.

Note : L'architecture 32 bits ne prend en charge que les applications Android 32 bits. L'architecture 64 bits compatible avec 32 bits prend en charge les applications Android 32 bits et 64 bits. L'architecture 64 bits sans compatibilité 32 bits ne prend en charge que les applications Android 64 bits.

  1. Facteurs affectant l'adaptation de l'APK aux architectures CPU - Code natif (C/C++) ================================

Pourquoi le code natif détermine-t-il l'architecture CPU compatible avec l'APK ? Pourquoi le code Java n'a-t-il pas d'impact ?

Le noyau du système Android est Linux, qui est écrit en langage C et assembleur. Le système Android est développé en Java, et le code Java doit appeler du code natif via JNI (Java Native Interface) pour accéder aux couches inférieures du système d'exploitation.

Pour s'adapter à différentes architectures CPU, il peut être nécessaire d'écrire du code natif différent en fonction de l'architecture CPU.

  1. Comment déterminer les architectures CPU prises en charge par un APK ? ==================

3.1 Vérification des architectures CPU prises en charge par un APK

Les APK utilisant généralement du code natif empaquettent celui-ci en bibliothèques .so pour être utilisées par le code Java. Par conséquent, pour déterminer les architectures CPU prises en charge par un APK, il suffit de vérifier les architectures des bibliothèques .qu'il contient.

Lors de la construction d'un APK, les bibliothèques .so de différentes architectures sont placées dans des dossiers distincts dans le dossier lib. La correspondance entre les architectures et les noms de dossiers est la suivante :

Architecture ARM :

32 bits : lib/armeabi-v7a, lib/armeabi

64 bits : lib/arm64-v8a

Architecture x86 :

32 bits : lib/x86

64 bits : lib/x86_64

La méthode pour déterminer les architectures CPU prises en charge par un APK consiste à examiner sa structure. Voici deux méthodes spécifiques :

Méthode 1 : Examiner les bibliothèques dans le dossier lib du package APK

Utilisez le menu Android Studio Build -> Analyze APK -> sélectionnez le APK à analyser. Dans les résultats, examinez le dossier lib. Si des dossiers armeabi, armeabi-v7a ou x86 sont présents, cela indique la présence de bibliothèques 32 bits. Si des dossiers x86_64 ou arm64-v8a sont présents, cela indique la présence de bibliothèques 64 bits. Si les deux types sont présents, l'APK prend en charge à la fois les architectures 32 bits et 64 bits.

Vous pouvez également changer l'extension du fichier APK en .zip, le décompresser et examiner le contenu du dossier lib.

Méthode 2 : Vérifier les bits des bibliothèques .so prises en charge dans le code de référence Android

Examinez le fichier build.gradle du module app, dans la balise android, puis dans la balise defaultConfig, puis dans la balise ndk, pour voir les bits des bibliothèques .so inclus dans abiFilters.

Les valeurs possibles pour abiFilters sont les suivantes (une application Android peut prendre en charge plusieurs architectures, séparées par des virgules) :

Architecture ARM :

32 bits : 'armeabi', 'armeabi-v7a'

64 bits : 'arm64-v8a'

Architecture x86 :

32 bits : 'x86'

64 bits : 'x86_64'

Si l'application Android n'utilise aucune bibliothèque .so, elle n'a pas de fonctionnalité active pour accéder directement au système d'exploitation. Dans ce cas, l'application est compatible avec les téléphones 32 bits et 64 bits sans problème de compatibilité matérielle. On peut qualifier cette application de package compatible 32 bits et 64 bits.

3.2 Relation de compatibilité entre bibliothèques .so de différentes architectures CPU Chargement des fichiers .so par les appareils Android

Lorsqu'une application est installée sur un appareil, seuls les fichiers .so correspondant à l'architecture CPU de l'appareil sont installés. Lors de l'exécution sur des appareils Android avec différentes architectures CPU, le système recherche dans le dossier libs le répertoire correspondant à son architecture et y charge les fichiers .so nécessaires. S'il n'y a pas de répertoire correspondant, il recherchera dans armeabi. Si un répertoire correspondant existe mais que le fichier .so n'y est pas trouvé, le système ne recherchera pas dans armeabi.

Lorsque abiFilters est configuré dans build.gradle du projet, soit tous les fichiers .SO correspondants au filtre sont présents, soit aucun ne l'est. L'application cherchera alors directement dans armeabi pour trouver les fichiers .SO afin de gérer la compatibilité.

android {
    defaultConfig {
        ndk {
            // Configuration des architectures de bibliothèques .SO prises en charge dans build.gradle de l'application
            abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a'
        }
    }
}

Adaptation à différentes plateformes

Actuellement, les appareils Android principaux utilisent l'architecture armeabi-v7a, suivis de x86 et armeabi. Si un APK contient simultanément armeabi, armeabi-v7a et x86, il peut s'exécuter sur tous les appareils. L'application chargera alors les .so correspondant à chaque plateforme lors de l'exécution. C'est une solution assez complète, mais elle augmente la taille du package.

armeabi-v7a est compatible avec armeabi, et les CPU v7a prennent en charge le calcul en virgule flottante matériel. La majorité des appareils sont maintenant armeabi-v7a, donc pour de meilleures performances, il n'est pas nécessaire d'inclure armeabi pour des raisons de compatibilité. x86 est également compatible avec l'exécution sur la plateforme armeabi. De plus, les bibliothèques .so compilées pour x86 sont généralement plus petites que celles pour armeabi. Pour les exigeants en termes de performance, il est recommandé de prendre en charge x86 lors de la compilation des .so.

Gestion des bibliothèques .so de tierces parties

Si une bibliothèque tierce ne fournit que des fichiers .so dans armeabi, et que votre projet prend en charge armeabi-v7a et x86, des problèmes peuvent survenir sur certains appareils Android si vous ne placez pas les fichiers .so correspondants dans les dossiers appropriés. Dans ce cas, vous pouvez copier les fichiers .so d'armeabi vers les autres dossiers. Si la bibliothèque tierce fournit des fichiers .so pour différentes plateformes, copiez simplement les fichiers .so correspondants dans les dossiers appropriés de votre projet.

  1. Adaptation de l'application aux politiques 64 bits - Rendre l'APK compatible avec les architectures 64 bits Raison :

Actuellement, l'architecture Arm va progressivement restreindre l'exécution des applications 32 bits. Les applications 32 bits ne peuvent s'exécuter que sur les petits cœurs, ce qui entraîne des problèmes de performance et de consommation d'énergie notables pour les applications purement 32 bits. Les appareils phare prévus pour fin 2023 ne prendront en charge que les applications 64 bits.

Interprétation de la politique :

Arm introduira une architecture qui ne prend en charge que les applications 64 bits. Par conséquent, les applications doivent être adaptées aux architetcures 64 bits pour garantir leur exécution correcte dans un environnement qui ne prend en charge que les applications 64 bits.

Solution pour la politique :

Il suffit de s'assurer que l'application contient des bibliothèques 64 bits. Si elles sont déjà présentes, aucune modification n'est nécessaire. Si elles sont absentes, il faut ajouter les bibliothèques 64 bits.

L'application n'a pas besoin de prendre en charge toutes les architectures 64 bits, mais pour chaque architecture native 32 bits qu'elle prend en charge, elle doit inclure l'architecture 64 bits correspondante.

  1. Comment Android Studio construit-il des APK prenant en charge différentes architectures ? Il suffit de modifier la valeur de abiFilters dans le fichier build.gradle, dans la balise android, puis dans la balise defaultConfig, puis dans la balise ndk, puis de générer le package.

Étiquettes: Android APK packaging CPU architecture

Publié le 12 juin à 20h30