Ce que cela signifie
Les appareils Android passent de pages mémoire de 4 Ko à 16 Ko. L'éditeur de liens dynamique place chaque segment LOAD d'une bibliothèque partagée sur une frontière de page : une bibliothèque alignée sur 4 Ko ne peut pas être chargée telle quelle sur un appareil à pages de 16 Ko. Les applications sans code natif (Kotlin ou Java uniquement) ne sont pas concernées.
La page de Google indique que toutes les applications qui ciblent Android 15 (API 35) ou plus doivent prendre en charge les pages mémoire de 16 Ko sur les appareils 64 bits sur Google Play. Deux points sont vérifiés : l'alignement ELF de chaque bibliothèque 64 bits (l'align de chaque segment LOAD doit valoir 2**14 ou plus) et, quand android:extractNativeLibs vaut false, la position de chaque bibliothèque non compressée dans l'APK (ce que vérifie zipalign -c -P 16).
Échéance
À partir du 1er février 2027, Google Play bloque la publication des mises à jour des applications qui ciblent l'API 35 ou plus sans prendre en charge les pages de 16 Ko. D'ici là, le contrôle le signale en avertissement ; à partir de cette date, en point bloquant.
Corriger
1. Repérer les bibliothèques mal alignées
Le contrôle liste chaque bibliothèque mal alignée avec son plus petit alignement LOAD. À la main, décompressez l'APK et inspectez chaque bibliothèque 64 bits :
llvm-objdump -p lib/arm64-v8a/libfoo.so | grep LOAD
# LOAD off 0x0000000 vaddr ... align 2**14 <- OK (16 Ko)
# LOAD off 0x0000000 vaddr ... align 2**12 <- 4 Ko, pas OK2. Recompiler votre propre code natif
Le NDK r28 et les versions suivantes produisent par défaut des bibliothèques alignées sur 16 Ko : mettre à jour le NDK est la correction la plus simple. Avec le NDK r27 ou plus ancien, passez les deux options à l'éditeur de liens :
target_link_options(foo PRIVATE
"-Wl,-z,max-page-size=16384"
"-Wl,-z,common-page-size=16384")3. Mettre à jour les SDK tiers qui embarquent des .so
La plupart des échecs viennent de bibliothèques précompilées dans les dépendances (SDK d'image, de vidéo, de base de données, de chiffrement, de moteur de jeu, d'analytics, anciens moteurs Flutter ou React Native). Le chemin de la bibliothèque dans le rapport désigne généralement le SDK. Passez à une version compilée pour les pages de 16 Ko ; recompiler soi-même une bibliothèque précompilée est rarement possible.
4. Empaqueter avec AGP 8.5.1 ou plus
Si l'APK stocke les bibliothèques natives sans compression (extractNativeLibs="false", la valeur par défaut avec un AGP récent), le plugin Android Gradle 8.5.1+ les aligne sur 16 Ko. Avec un plugin plus ancien, la solution de repli est packaging { jniLibs { useLegacyPackaging = true } }, qui compresse les bibliothèques et augmente la taille de l'application installée. Un App Bundle (AAB) n'est pas concerné : Google Play génère et aligne lui-même les APK.
Vérifier avant de soumettre
Déposez l'APK, AAB ou lot d'APK fractionnés (XAPK, APKS, APKM) sur la page de contrôle des stores. Elle exécute PLAY-16KB-ELF PLAY-16KB-ZIPALIGN avec les dates de cette page, puis supprime le fichier : rien de l'application n'est conservé. Le même moteur tourne hors ligne dans la CLI Narvy et renvoie le code 1 quand un point bloquant est trouvé, ce qui permet de bloquer un job de CI.
Les commandes de Google donnent la même réponse : zipalign -c -P 16 -v 4 app.apk pour un APK, bundletool dump config --bundle=app.aab | grep alignment pour un bundle (résultat attendu : PAGE_ALIGNMENT_16K).
narvy store-check app-release.aab --lang frQuestions fréquentes
Mon application n'a pas de code C ou C++. Pourquoi est-elle signalée ?
Parce qu'une dépendance embarque une bibliothèque native. Regardez les chemins du rapport (lib/arm64-v8a/lib*.so) : chacun provient d'un SDK ou d'un framework de votre build.
La bibliothèque 32 bits armeabi-v7a doit-elle être alignée ?
Non. L'exigence porte sur les appareils 64 bits : seules les bibliothèques arm64-v8a et x86_64 sont vérifiées.
J'envoie un App Bundle. L'alignement dans l'archive compte-t-il ?
Non : Google Play génère les APK à partir du bundle et les aligne lui-même, le contrôle marque donc l'alignement dans l'archive comme non applicable. L'alignement ELF de chaque bibliothèque compte toujours.