Restrictions concernant les interfaces non SDK

À partir d'Android 9 (niveau d'API 28), la plate-forme limite les interfaces non SDK que votre application peut utiliser. Ces restrictions s'appliquent chaque fois qu'une application fait référence à une interface non SDK ou tente d'obtenir son identifiant à l'aide de la réflexion ou de JNI. Ces restrictions ont été mises en place pour améliorer l'expérience utilisateur et celle des développeurs, et réduire les risques de déploiements d'urgence pour les développeurs et les risques de plantage pour les utilisateurs. Pour en savoir plus sur cette décision, consultez Améliorer la stabilité en réduisant l'utilisation d'interfaces non SDK.

Faire la distinction entre les interfaces SDK et non SDK

De manière générale, les interfaces SDK publiques sont celles décrites dans l'index des packages du framework Android. La gestion des interfaces non SDK est un détail d'implémentation que l'API élimine. Ces interfaces sont donc susceptibles d'être modifiées sans préavis.

Pour éviter les plantages et les comportements inattendus, les applications ne doivent utiliser que les parties de classe officiellement documentées dans le SDK. Cela signifie également que vous ne devez pas accéder à des méthodes ou à des champs qui ne sont pas répertoriés dans le SDK lorsque vous interagissez avec une classe à l'aide de mécanismes tels que la réflexion.

Listes d'API non SDK

À chaque version d'Android, des interfaces non SDK supplémentaires sont restreintes. Nous savons que ces restrictions peuvent avoir un impact sur votre workflow de publication. Nous voulons donc nous assurer que vous disposez des outils permettant de détecter l'utilisation d'interfaces non SDK, la possibilité de nous faire part de vos commentaires, et le temps de planifier et de vous adapter aux nouvelles règles.

Pour minimiser l'impact des restrictions non SDK sur votre workflow de développement, les interfaces non SDK sont divisées en listes qui définissent le degré de restriction de leur utilisation, en fonction du niveau d'API ciblé. Le tableau suivant décrit chacune de ces listes:

Liste Tags de code Description
Liste de blocage
  • blocked
  • Obsolète: blacklist
Interfaces non SDK que vous ne pouvez pas utiliser quel que soit le niveau d'API cible de votre application. Si votre application tente d'accéder à l'une de ces interfaces, le système génère une erreur.
Bloquée de manière conditionnelle
  • max-target-x
  • Obsolète: greylist-max-x

À partir d'Android 9 (niveau d'API 28), chaque niveau d'API comporte des interfaces non SDK qui sont limitées lorsqu'une application cible ce niveau d'API.

Ces listes sont identifiées par le niveau d'API maximal (max-target-x) qu'une application peut cibler avant de ne plus pouvoir accéder aux interfaces non SDK de cette liste. Par exemple, une interface non SDK qui n'a pas été bloquée dans Android Pie, mais qui l'est désormais dans Android 10, fait partie de la liste max-target-p (greylist-max-p), où "p" correspond à Pie ou Android 9 (niveau d'API 28).

Si votre application tente d'accéder à une interface restreinte pour votre niveau d'API cible, le système se comporte comme si l'API faisait partie de la liste de blocage.

Non compatible
  • unsupported
  • Obsolète: greylist
Interfaces non SDK qui ne sont pas restreintes et que votre application peut utiliser. Notez toutefois que ces interfaces ne sont pas compatibles et peuvent être modifiées sans préavis. Attendez-vous à ce que ces interfaces soient bloquées de manière conditionnelle dans les futures versions d'Android dans une liste max-target-x.
SDK
  • public-api et sdk
  • Obsolètes: public-api et whitelist.
Interfaces pouvant être utilisées librement et désormais prises en charge dans l'index des packages du framework Android officiellement documenté.
API de test
  • test-api
Interfaces utilisées pour les tests système internes, tels que les API qui facilitent les tests via la suite de tests de compatibilité (CTS, Compatibility Test Suite). Les API de test ne font pas partie du SDK. À partir d'Android 11 (niveau d'API 30), les API de test sont incluses dans la liste de blocage. Les applications ne sont donc pas autorisées à les utiliser, quel que soit leur niveau d'API cible. Toutes les API de test ne sont pas compatibles et peuvent être modifiées sans préavis, quel que soit le niveau d'API de la plate-forme.

Bien que vous puissiez utiliser certaines interfaces non SDK (en fonction du niveau d'API cible de votre application), l'utilisation d'une méthode ou d'un champ autre que SDK présente toujours un risque élevé de dysfonctionnement de votre application. Si votre application repose sur des interfaces non SDK, vous devez commencer à planifier une migration vers des interfaces SDK ou d'autres alternatives. Si vous ne trouvez pas d'alternative à l'utilisation d'une interface non SDK pour une fonctionnalité de votre application, vous devez demander une nouvelle API publique.

Déterminer la liste à laquelle une interface appartient

Les listes d'interfaces non SDK sont créées dans le cadre de la plate-forme. Consultez les sections suivantes pour en savoir plus sur chaque version d'Android.

Android 15 (preview développeur)

Pour Android 15, vous pouvez télécharger le fichier suivant, qui décrit toutes les interfaces non SDK et les listes correspondantes:

Fichier: hiddenapi-flags.csv

Somme de contrôle SHA-256 : 7aa0987aea4b25f5371b7e377c9f37375ada3b7e30465c0e2d910a5b646c10c1

Pour en savoir plus sur les modifications apportées à la liste des API non SDK dans Android 15, consultez Mises à jour des restrictions des interfaces non SDK dans Android 15.

Android 14

Pour Android 14 (niveau d'API 34), vous pouvez télécharger le fichier suivant, qui décrit toutes les interfaces non SDK et les listes correspondantes:

Fichier: hiddenapi-flags.csv

Somme de contrôle SHA-256 : 7e00db074cbe51c51ff4b411f7b48e98692951395c5c17d069c822cc1d0eae0f

Pour en savoir plus sur les modifications apportées à la liste des API non SDK dans Android 14, consultez Mises à jour des restrictions des interfaces non SDK dans Android 14.

Android 13

Pour Android 13 (niveau d'API 33), vous pouvez télécharger le fichier suivant, qui décrit toutes les interfaces non SDK, ainsi que les listes correspondantes :

Fichier: hiddenapi-flags.csv

Somme de contrôle SHA-256 : 233a277aa8ac475b6df61bffd95665d86aac6eb2ad187b90bf42a98f5f2a11a3

Pour en savoir plus sur les modifications apportées à la liste des API non SDK dans Android 13, y compris les suggestions d'alternatives dans les API publiques pour les API bloquées de manière conditionnelle dans Android 13, consultez Mises à jour des restrictions d'interface non SDK dans Android 13.

Android 12

Pour Android 12 (niveau d'API 31), vous pouvez télécharger le fichier suivant, qui décrit toutes les interfaces non SDK et les listes correspondantes:

Fichier: hiddenapi-flags.csv

Somme de contrôle SHA-256 : 40674ff4291eb268f86561bf687e69dbd013df9ec9531a460404532a4ac9a761

Pour en savoir plus sur les modifications apportées à la liste des API non SDK dans Android 12, y compris les suggestions d'alternatives dans les API publiques pour les API bloquées de manière conditionnelle dans Android 12, consultez Modification des listes pour Android 12.

Android 11

Pour Android 11 (niveau d'API 30), vous pouvez télécharger le fichier suivant, qui décrit toutes les interfaces non SDK, ainsi que les listes correspondantes :

Fichier: hiddenapi-flags.csv

Somme de contrôle SHA-256 : a19d839f4f61dc9c94960ae977b2e0f3eb30f880ba1ffe5108e790010b477a56

Pour en savoir plus sur les modifications apportées à la liste des API non SDK dans Android 11, y compris les suggestions d'alternatives dans les API publiques pour les API bloquées de manière conditionnelle dans Android 11, consultez Modifications des listes pour Android 11.

Android 10

Pour Android 10 (niveau d'API 29), vous pouvez télécharger le fichier suivant, qui décrit toutes les interfaces non SDK, ainsi que les listes correspondantes :

Fichier: hiddenapi-flags.csv

Somme de contrôle SHA-256 : f22a59c215e752777a114bd9b07b0b6b4aedfc8e49e6efca0f99681771c5bfeb

Pour en savoir plus sur les modifications apportées à la liste des API non SDK dans Android 10, y compris les suggestions d'alternatives dans les API publiques pour les API bloquées de manière conditionnelle dans Android 10, consultez Modifications des listes pour Android 10.

Android 9

Pour Android 9 (niveau d'API 28), le fichier texte suivant contient la liste des API non SDK qui ne sont pas limitées (sur liste grise) : hiddenapi-light-greylist.txt.

La liste de blocage (blacklist) et la liste des API bloquées de manière conditionnelle (liste gris foncé) sont dérivées de ce fichier lors de la compilation.

Générer des listes à partir d'AOSP

Lorsque vous travaillez avec AOSP, vous pouvez générer un fichier hiddenapi-flags.csv contenant toutes les interfaces non SDK et les listes correspondantes. Pour ce faire, téléchargez la source AOSP, puis exécutez la commande suivante:

m out/soong/hiddenapi/hiddenapi-flags.csv

Vous trouverez alors le fichier à l'emplacement suivant :

out/soong/hiddenapi/hiddenapi-flags.csv

Comportement attendu lors de l'accès à des interfaces non SDK restreintes

Le tableau suivant décrit le comportement auquel vous pouvez vous attendre si votre application tente d'accéder à une interface non SDK faisant partie de la liste de blocage.

Moyens d'accès Résultat
Instruction Dalvik faisant référence à un champ NoSuchFieldError générée
Instruction Dalvik faisant référence à une méthode NoSuchMethodError générée
Réflexion utilisant Class.getDeclaredField() ou Class.getField() NoSuchFieldException générée
Réflexion avec Class.getDeclaredMethod(), Class.getMethod() NoSuchMethodException générée
Réflexion avec Class.getDeclaredFields(), Class.getFields() Les membres non SDK n'apparaissent pas dans les résultats
Réflexion avec Class.getDeclaredMethods(), Class.getMethods() Les membres non SDK n'apparaissent pas dans les résultats
JNI utilisant env->GetFieldID() NULL renvoyé, NoSuchFieldError générée
JNI utilisant env->GetMethodID() NULL renvoyé, NoSuchMethodError générée

Tester votre application pour les interfaces non SDK

Plusieurs méthodes existent pour tester des interfaces non SDK dans votre application.

Tester à l'aide d'une application débogable

Vous pouvez tester les interfaces non SDK en créant et en exécutant une application débogable sur un appareil ou un émulateur exécutant Android 9 (niveau d'API 28) ou une version ultérieure. Assurez-vous que l'appareil ou l'émulateur que vous utilisez correspond au niveau d'API cible de votre application.

Lors des tests sur votre application, le système affiche un message de journal si votre application accède à certaines interfaces non SDK. Vous pouvez inspecter les messages de journal de votre application pour trouver les informations suivantes :

  • Classe, nom et type déclarants (au format utilisé par l'environnement d'exécution Android).
  • Moyen d'accès: par liaison, par réflexion ou via JNI.
  • Liste à laquelle appartient l'interface non SDK.

Vous pouvez utiliser adb logcat pour accéder à ces messages de journal, qui apparaissent sous le PID de l'application en cours d'exécution. Par exemple, une entrée du journal peut se présenter comme suit :

Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)

Test à l'aide de l'API StrictMode

Vous pouvez également tester la présence d'interfaces non SDK à l'aide de l'API StrictMode. Pour ce faire, utilisez la méthode detectNonSdkApiUsage. Après avoir activé l'API StrictMode, vous pouvez recevoir un rappel pour chaque utilisation d'une interface non SDK à l'aide d'un penaltyListener, dans lequel vous pouvez implémenter le traitement personnalisé. L'objet Violation fourni dans le rappel provient de Throwable, et la trace de la pile incluse fournit le contexte de l'utilisation.

Test avec l'outil veridex

Vous pouvez également exécuter l'outil d'analyse statique veridex sur votre APK. L'outil veridex analyse l'intégralité du codebase de l'APK, y compris les bibliothèques tierces, et signale toute utilisation d'interfaces non SDK qu'il trouve.

Les limites de l'outil veridex sont les suivantes :

  • Il ne peut pas détecter les appels via JNI.
  • Il ne peut détecter qu'un sous-ensemble d'appels par réflexion.
  • Son analyse des chemins de code inactifs est limitée aux vérifications au niveau de l'API.
  • Il ne peut être exécuté que sur des machines compatibles avec les instructions SSE4.2 et POPCNT.

Windows

Les binaires Windows natifs ne sont pas fournis, mais vous pouvez exécuter l'outil veridex sous Windows en exécutant les binaires Linux à l'aide du sous-système Windows pour Linux (WSL). Avant de suivre les étapes de cette section, installez le WSL et choisissez Ubuntu comme distribution Linux.

Une fois Ubuntu installé, lancez un terminal Ubuntu, puis procédez comme suit :

  1. Téléchargez l'outil veridex à partir du dépôt des builds prédéfinis de l'environnement d'exécution Android.
  2. Extrayez le contenu du fichier appcompat.tar.gz.
  3. Dans le dossier extrait, localisez le fichier veridex-linux.zip et extrayez-le.
  4. Accédez au dossier décompressé, puis exécutez la commande suivante, où your-app.apk est l'APK que vous souhaitez tester :

    ./appcompat.sh --dex-file=your-app.apk
    

macOS

Pour exécuter l'outil veridex sur macOS, procédez comme suit :

  1. Téléchargez l'outil veridex à partir du dépôt des builds prédéfinis de l'environnement d'exécution Android.
  2. Extrayez le contenu du fichier appcompat.tar.gz.
  3. Dans le dossier extrait, localisez le fichier veridex-mac.zip et extrayez-le.
  4. Accédez au dossier décompressé, puis exécutez la commande suivante, où /path-from-root/your-app.apk est le chemin d'accès à l'APK que vous souhaitez tester, à partir du répertoire racine de votre système:

    ./appcompat.sh --dex-file=/path-from-root/your-app.apk
    

Linux

Pour exécuter l'outil veridex sous Linux, procédez comme suit :

  1. Téléchargez l'outil veridex à partir du dépôt des builds prédéfinis de l'environnement d'exécution Android.
  2. Extrayez le contenu du fichier appcompat.tar.gz.
  3. Dans le dossier extrait, localisez le fichier veridex-linux.zip et extrayez-le.
  4. Accédez au dossier décompressé, puis exécutez la commande suivante, où your-app.apk est l'APK que vous souhaitez tester :

    ./appcompat.sh --dex-file=your-app.apk
    

Test avec l'outil d'analyse lint d'Android Studio

Chaque fois que vous compilez votre application dans Android Studio, l'outil lint inspecte votre code pour détecter d'éventuels problèmes. Si votre application utilise des interfaces non SDK, des erreurs de compilation ou des avertissements peuvent s'afficher, selon la liste à laquelle ces interfaces appartiennent.

Vous pouvez également exécuter l'outil lint à partir de la ligne de commande ou exécuter des inspections manuellement sur un projet, un dossier ou un fichier spécifique.

Test à l'aide de la Play Console

Lorsque vous importez votre application dans un canal de test dans la Play Console, elle est automatiquement testée pour détecter d'éventuels problèmes et un rapport pré-lancement est généré. Si votre application utilise des interfaces non SDK, une erreur ou un avertissement s'affiche dans le rapport pré-lancement, selon la liste à laquelle ces interfaces appartiennent.

Pour en savoir plus, consultez la section "Compatibilité Android" dans Utiliser les rapports pré-lancement pour identifier les problèmes.

Demander une nouvelle API publique

Si vous ne trouvez pas d'alternative à l'utilisation d'une interface non SDK pour une fonctionnalité de votre application, vous pouvez demander une nouvelle API publique en créant une demande de fonctionnalité dans notre outil Issue Tracker.

Lorsque vous créez une demande de fonctionnalité, fournissez les informations suivantes:

  • L'API non compatible que vous utilisez, y compris le descripteur complet indiqué dans le message logcat Accessing hidden ....
  • Pourquoi utiliser ces API, y compris des détails sur la fonctionnalité de haut niveau pour laquelle l'API est nécessaire, et pas seulement des détails de bas niveau.
  • La raison pour laquelle les API de SDK publiques associées ne suffisent pas à répondre à vos besoins.
  • Toutes les autres solutions que vous avez essayées et les raisons pour lesquelles elles n'ont pas fonctionné.

En fournissant ces informations dans votre demande de fonctionnalité, vous augmentez la probabilité que votre demande de nouvelle API publique soit acceptée.

Autres questions

Cette section inclut des réponses aux autres questions fréquemment posées par les développeurs :

Questions générales

Comment Google peut-il s'assurer de pouvoir répondre aux besoins de toutes les applications via l'outil Issue Tracker ?

Nous avons créé les listes initiales pour Android 9 (niveau d'API 28) à l'aide d'une analyse statique des applications, qui a été complétée à l'aide des méthodes suivantes :

  • Test manuel des principales applications Google Play et autres
  • Rapports internes
  • Collecte automatique des données auprès des utilisateurs internes
  • Rapports des previews développeur
  • Analyse statique supplémentaire conçue pour inclure de façon prudente plus de faux positifs

Lorsque nous évaluons les listes de chaque nouvelle version, nous prenons en compte l'utilisation de l'API ainsi que les commentaires des développeurs via l'outil Issue Tracker.

Comment puis-je activer l'accès aux interfaces non SDK ?

Vous pouvez activer l'accès aux interfaces non SDK sur des appareils de développement en modifiant la règle d'application des API à l'aide des commandes adb. Les commandes que vous utilisez varient en fonction du niveau de l'API. Ces commandes ne nécessitent pas d'appareil en mode root.

Android 10 (niveau d'API 29) ou version ultérieure

Pour activer l'accès, utilisez l'adb suivant :

command:

adb shell settings put global hidden_api_policy  1

Pour rétablir les paramètres par défaut de la règle d'application des API, utilisez la commande suivante:

adb shell settings delete global hidden_api_policy
Android 9 (niveau d'API 28)

Pour activer l'accès, utilisez les commandes adb suivantes :

adb shell settings put global hidden_api_policy_pre_p_apps  1
adb shell settings put global hidden_api_policy_p_apps 1

Pour rétablir les paramètres par défaut de la règle d'application des API, utilisez les commandes suivantes:

adb shell settings delete global hidden_api_policy_pre_p_apps
adb shell settings delete global hidden_api_policy_p_apps

Vous pouvez définir l'entier dans la règle d'application des API sur l'une des valeurs suivantes :

  • 0 : Désactiver toute détection des interfaces non SDK. L'utilisation de ce paramètre désactive tous les messages de journal pour une utilisation d'interface non SDK, et vous empêche de tester votre application à l'aide de l'API StrictMode. Ce paramètre n'est pas recommandé.
  • 1 : Activer l'accès à toutes les interfaces non SDK, mais afficher des messages de journal contenant des avertissements pour toute utilisation d'interface non SDK. Ce paramètre vous permet également de tester votre application à l'aide de l'API StrictMode.
  • 2 : Interdire l'utilisation d'interfaces non SDK appartenant à la liste de blocage ou bloquées de manière conditionnelle pour votre niveau d'API cible.

Questions sur les listes d'interfaces non SDK

Où puis-je trouver les listes d'API non SDK dans l'image système ?

Elles sont encodées dans le champ et dans les bits d'indicateur d'accès à la méthode dans les fichiers dex de la plate-forme. L'image système ne contient pas de fichier distinct contenant ces listes.

Les listes des API non SDK sont-elles identiques sur différents appareils OEM avec les mêmes versions d'Android ?

Les appareils OEM peuvent ajouter leurs propres interfaces à la liste de blocage (liste noire), mais ne peuvent pas supprimer d'interfaces des listes d'API non SDK d'AOSP. Le CDD empêche ces modifications et les tests CTS garantissent qu'Android Runtime applique la liste.

Existe-t-il des restrictions pour les interfaces non NDK en code natif ?

Le SDK Android inclut des interfaces Java. La plate-forme a commencé à restreindre l'accès aux interfaces non SDK pour le code C/C++ natif dans Android 7 (niveau d'API 26). Pour en savoir plus, consultez Améliorer la stabilité avec les restrictions de symboles C/C++ privées dans Android N.

Est-il possible de limiter la manipulation des fichiers dex2oat ou DEX ?

Nous n'avons pas l'intention de restreindre l'accès au binaire dex2oat, mais nous ne souhaitons pas que le format de fichier DEX soit stable ou qu'il constitue une interface publique au-delà des parties spécifiées publiquement dans le format Dalvik Executable. Nous nous réservons le droit de modifier ou d'éliminer dex2oat et les parties non spécifiées du format DEX à tout moment. Notez également que les fichiers dérivés produits par dex2oat tels que ODEX (également appelé OAT), VDEX et CDEX sont tous des formats non spécifiés.

Que se passe-t-il si un SDK tiers essentiel (par exemple, un offuscateur) ne peut pas éviter d'utiliser des interfaces non SDK, mais s'engage à maintenir la compatibilité avec les futures versions d'Android ? Dans ce cas, Android peut-il renoncer à ses exigences de compatibilité ?

Nous ne prévoyons pas de renoncer aux exigences de compatibilité pour chaque SDK. Si un développeur de SDK ne peut assurer la compatibilité qu'en fonction des interfaces des listes non compatibles (anciennement grises), il doit commencer à planifier une migration vers des interfaces SDK ou d'autres alternatives, et demander une nouvelle API publique lorsqu'il ne trouve pas d'alternative à l'utilisation d'une interface non SDK.

Les restrictions d'interface non SDK s'appliquent-elles à toutes les applications, y compris les applications système et propriétaires, et pas seulement aux applications tierces ?

Oui. Toutefois, les applications signées avec la clé de plate-forme et certaines applications d'image système sont exemptées. Notez que ces exceptions ne s'appliquent qu'aux applications qui font partie de l'image système (ou aux applications qui font partie de l'image système et qui ont été mises à jour). La liste est destinée uniquement aux applications compilées avec les API de la plate-forme privée, et non avec les API du SDK (c'est-à-dire LOCAL_PRIVATE_PLATFORM_APIS := true).