En plus de nouvelles fonctionnalités, Android 7.0 inclut divers changements de comportement du système et des API. Ce document présente certains des principaux changements que vous devez comprendre et prendre en compte dans vos applications.
Si vous avez déjà publié une application pour Android, sachez que ces modifications de la plate-forme peuvent l'affecter.
Batterie et mémoire
Android 7.0 inclut des modifications du comportement du système visant à améliorer l'autonomie de la batterie des appareils et à réduire l'utilisation de la RAM. Ces modifications peuvent affecter l'accès de votre application aux ressources système, ainsi que la façon dont elle interagit avec d'autres applications à l'aide de certains intents implicites.
Sommeil
Introduit dans Android 6.0 (niveau d'API 23), le mode Doze améliore l'autonomie de la batterie en différant les activités du processeur et les activités réseau lorsqu'un utilisateur laisse un appareil débranché, immobile et avec l'écran éteint. Android 7.0 apporte d'autres améliorations au mode Doze en appliquant un sous-ensemble de restrictions du processeur et du réseau lorsque l'appareil est débranché avec l'écran éteint, mais pas nécessairement immobile, par exemple lorsqu'un téléphone est dans la poche d'un utilisateur.
Figure 1. Illustration de la façon dont le mode Sommeil applique un premier niveau de restrictions d'activité du système pour améliorer l'autonomie de la batterie.
Lorsqu'un appareil est alimenté par batterie et que l'écran est éteint depuis un certain temps, l'appareil passe en mode Sommeil et applique le premier sous-ensemble de restrictions : il désactive l'accès réseau des applications, et reporte les tâches et les synchronisations. Si l'appareil reste immobile pendant un certain temps après l'activation du mode Doze, le système applique les autres restrictions du mode Doze aux alarmes PowerManager.WakeLock et AlarmManager, au GPS et aux recherches de réseaux Wi-Fi. Que certaines ou toutes les restrictions du mode Doze soient appliquées, le système réveille l'appareil pendant de brefs intervalles de maintenance, au cours desquels les applications sont autorisées à accéder au réseau et peuvent exécuter les tâches/synchronisations différées.
Figure 2. Illustration montrant comment le mode Doze applique un deuxième niveau de restrictions d'activité du système après que l'appareil est resté immobile pendant un certain temps.
Notez que l'activation de l'écran ou le branchement de l'appareil désactive le mode Doze et supprime ces restrictions de traitement. Le comportement supplémentaire n'affecte pas les recommandations ni les bonnes pratiques d'adaptation de votre application à la version précédente du mode Sommeil introduite dans Android 6.0 (niveau d'API 23), comme indiqué dans Optimiser pour les modes Sommeil et Mise en veille des applications. Vous devez toujours suivre ces recommandations, par exemple en utilisant Firebase Cloud Messaging (FCM) pour envoyer et recevoir des messages, et commencer à planifier des mises à jour pour tenir compte du comportement supplémentaire du mode Doze.
Projet Svelte : optimisations en arrière-plan
Android 7.0 supprime trois diffusions implicites afin d'optimiser l'utilisation de la mémoire et la consommation d'énergie. Cette modification est nécessaire, car les diffusions implicites démarrent fréquemment des applications qui se sont enregistrées pour les écouter en arrière-plan. La suppression de ces diffusions peut améliorer considérablement les performances de l'appareil et l'expérience utilisateur.
Les appareils mobiles subissent de fréquents changements de connectivité, par exemple lorsqu'ils passent du Wi-Fi aux données mobiles. Actuellement, les applications peuvent surveiller les changements de connectivité en enregistrant un récepteur pour la diffusion implicite CONNECTIVITY_ACTION dans leur fichier manifeste. Étant donné que de nombreuses applications s'enregistrent pour recevoir cette diffusion, un seul commutateur réseau peut toutes les réveiller et traiter la diffusion en même temps.
De même, dans les versions précédentes d'Android, les applications pouvaient s'enregistrer pour recevoir des diffusions ACTION_NEW_PICTURE et ACTION_NEW_VIDEO implicites d'autres applications, comme l'appareil photo. Lorsqu'un utilisateur prend une photo avec l'application Appareil photo, ces applications se réveillent pour traiter la diffusion.
Pour réduire ces problèmes, Android 7.0 applique les optimisations suivantes :
- Les applications ciblant Android version 7.0 (niveau 24 d'API) et ultérieures ne reçoivent pas les diffusions
CONNECTIVITY_ACTIONs'ils déclarent leur récepteur de diffusion dans le fichier manifeste. Les applications continueront à recevoir des diffusionsCONNECTIVITY_ACTIONsi elles enregistrent leurBroadcastReceiverauprès deContext.registerReceiver()et que ce contexte est toujours valide. - Le système n'envoie plus de diffusions
ACTION_NEW_PICTUREniACTION_NEW_VIDEO. Cette optimisation concerne toutes les applications, pas seulement celles qui ciblent Android 7.0.
Si votre application utilise l'un de ces intents, supprimez les dépendances dès que possible afin de pouvoir cibler correctement les appareils équipés d'Android 7.0.
Le framework Android fournit plusieurs solutions pour réduire le besoin de ces diffusions implicites. Par exemple, l'API JobScheduler fournit un mécanisme robuste pour planifier les opérations réseau lorsque certaines conditions, telles qu'une connexion à un réseau sans compteur, sont remplies. Vous pouvez même utiliser JobScheduler pour réagir aux changements apportés aux fournisseurs de contenu.
Pour en savoir plus sur les optimisations en arrière-plan dans Android 7.0 (niveau d'API 24) et sur la façon d'adapter votre application, consultez Optimisations en arrière-plan.
Modifications des autorisations
Android 7.0 inclut des modifications des autorisations qui peuvent affecter votre application.
Modifications des autorisations du système de fichiers
Afin d'améliorer la sécurité des fichiers privés, l'accès au répertoire privé des applications ciblant Android 7.0 ou version ultérieure est limité (0700). Ce paramètre empêche la fuite des métadonnées des fichiers privés, telles que leur taille ou leur existence. Cette modification des autorisations a plusieurs effets secondaires :
-
Le propriétaire ne doit plus assouplir les autorisations des fichiers privés. Toute tentative en ce sens à l'aide de
MODE_WORLD_READABLEet/ou deMODE_WORLD_WRITEABLEdéclenchera uneSecurityException.Remarque : Pour l'instant, cette restriction n'est pas entièrement appliquée. Les applications peuvent toujours modifier les autorisations de leur répertoire privé à l'aide d'API natives ou de l'API
File. Cependant, nous vous déconseillons fortement d'assouplir les autorisations d'accès au répertoire privé. -
La transmission d'URI
file://en dehors du domaine du package peut laisser le récepteur avec un chemin inaccessible. Par conséquent, les tentatives de transmission d'un URIfile://déclenchent une erreurFileUriExposedException. La méthode recommandée pour partager le contenu d'un fichier privé consiste à utiliserFileProvider. -
DownloadManagerne peut plus partager de fichiers stockés de manière privée par nom de fichier. Les anciennes applications peuvent se retrouver avec un chemin d'accès inaccessible lors de l'accès àCOLUMN_LOCAL_FILENAME. Les applications ciblant Android 7.0 ou version ultérieure déclenchent uneSecurityExceptionlorsqu'elles tentent d'accéder àCOLUMN_LOCAL_FILENAME. Les anciennes applications qui définissent l'emplacement de téléchargement sur un emplacement public à l'aide deDownloadManager.Request.setDestinationInExternalFilesDir()ouDownloadManager.Request.setDestinationInExternalPublicDir()peuvent toujours accéder au chemin d'accès dansCOLUMN_LOCAL_FILENAME. Toutefois, cette méthode est fortement déconseillée. La méthode privilégiée pour accéder à un fichier exposé parDownloadManagerconsiste à utiliserContentResolver.openFileDescriptor().
Partager des fichiers entre des applications
Pour les applications ciblant Android 7.0, le framework Android applique la règle d'API StrictMode qui interdit l'exposition des URI file:// en dehors de votre application. Si un intent contenant un URI de fichier quitte votre application, celle-ci échoue avec une exception FileUriExposedException.
Pour partager des fichiers entre des applications, vous devez envoyer un URI content:// et accorder une autorisation d'accès temporaire à l'URI. Le moyen le plus simple d'accorder cette autorisation consiste à utiliser la classe FileProvider. Pour en savoir plus sur les autorisations et le partage de fichiers, consultez Partager des fichiers.
Améliorations liées à l'accessibilité
Android 7.0 inclut des modifications visant à améliorer l'ergonomie de la plate-forme pour les utilisateurs malvoyants ou souffrant d'une déficience visuelle. En général, ces modifications ne nécessitent pas de modifier le code de votre application. Toutefois, vous devez examiner ces fonctionnalités et les tester avec votre application pour évaluer les impacts potentiels sur l'expérience utilisateur.
Zoom sur l'écran
Android 7.0 permet aux utilisateurs de définir la taille d'affichage, qui agrandit ou réduit tous les éléments à l'écran, améliorant ainsi l'accessibilité de l'appareil pour les utilisateurs souffrant d'une déficience visuelle. Les utilisateurs ne peuvent pas zoomer sur l'écran au-delà d'une largeur d'écran minimale de sw320dp, qui correspond à la largeur d'un Nexus 4, un téléphone de taille moyenne courant.
Figure 3. L'écran de droite montre l'effet de l'augmentation de la taille d'affichage d'un appareil exécutant une image système Android 7.0.
Lorsque la densité de l'appareil change, le système en informe les applications en cours d'exécution de la manière suivante :
- Si une application cible le niveau d'API 23 ou inférieur, le système arrête automatiquement tous ses processus en arrière-plan. Cela signifie que si un utilisateur quitte une telle application pour ouvrir l'écran Paramètres et modifier le paramètre Taille d'affichage, le système arrête l'application de la même manière qu'en cas de mémoire insuffisante. Si l'application comporte des processus de premier plan, le système les informe de la modification de configuration, comme décrit dans Gérer les modifications d'exécution, comme si l'orientation de l'appareil avait changé.
- Si une application cible Android 7.0, tous ses processus (premier plan et arrière-plan) sont informés de la modification de configuration, comme décrit dans Gérer les modifications d'exécution.
La plupart des applications n'ont pas besoin d'être modifiées pour prendre en charge cette fonctionnalité, à condition qu'elles respectent les bonnes pratiques Android. Points spécifiques à vérifier :
- Testez votre application sur un appareil dont la largeur d'écran est de
sw320dpet assurez-vous qu'elle fonctionne correctement. - Lorsque la configuration de l'appareil change, mettez à jour toutes les informations mises en cache dépendantes de la densité, telles que les bitmaps mis en cache ou les ressources chargées à partir du réseau. Vérifiez si des modifications de configuration ont été apportées lorsque l'application reprend après avoir été mise en pause.
Remarque : Si vous mettez en cache des données dépendantes de la configuration, il est judicieux d'inclure des métadonnées pertinentes, telles que la taille d'écran ou la densité de pixels appropriées pour ces données. L'enregistrement de ces métadonnées vous permet de décider si vous devez actualiser les données mises en cache après une modification de la configuration.
- Évitez de spécifier des dimensions avec des unités px, car elles ne s'adaptent pas à la densité de l'écran. Spécifiez plutôt les dimensions en unités de pixels indépendants de la densité (
dp).
Paramètres visuels dans l'assistant de configuration
Android 7.0 inclut les paramètres de vision sur l'écran d'accueil, où les utilisateurs peuvent configurer les paramètres d'accessibilité suivants sur un nouvel appareil : Geste d'agrandissement, Taille de police, Taille d'affichage et TalkBack. Cette modification augmente la visibilité des bugs liés aux différents paramètres d'écran. Pour évaluer l'impact de cette fonctionnalité, vous devez tester vos applications avec ces paramètres activés. Vous trouverez les paramètres sous Paramètres > Accessibilité.
Association d'applications NDK à des bibliothèques de plate-forme
À partir d'Android 7.0, le système empêche les applications d'établir une liaison dynamique avec des bibliothèques non NDK, ce qui peut entraîner le plantage de votre application. Ce changement de comportement vise à créer une expérience dans l'application cohérente entre les mises à jour de la plate-forme et les différents appareils. Même si votre code n'est pas associé à des bibliothèques privées, il est possible qu'une bibliothèque statique tierce de votre application le soit. Par conséquent, tous les développeurs doivent s'assurer que leurs applications ne plantent pas sur les appareils équipés d'Android 7.0. Si votre application utilise du code natif, vous ne devez utiliser que les API NDK publiques.
Votre application peut tenter d'accéder aux API de la plate-forme privée de trois manières :
- Votre application accède directement à des bibliothèques de plate-forme privées. Vous devez mettre à jour votre application pour inclure sa propre copie de ces bibliothèques ou utiliser les API NDK publiques.
- Votre application utilise une bibliothèque tierce qui accède à des bibliothèques de plates-formes privées. Même si vous êtes certain que votre application n'accède pas directement à des bibliothèques privées, vous devez quand même la tester pour ce scénario.
- Votre application fait référence à une bibliothèque qui n'est pas incluse dans son APK. Par exemple, cela peut se produire si vous avez essayé d'utiliser votre propre copie d'OpenSSL, mais que vous avez oublié de l'intégrer à l'APK de votre application. L'application peut s'exécuter normalement sur les versions de la plate-forme Android qui incluent
libcrypto.so. Toutefois, l'application peut planter sur les versions ultérieures d'Android qui n'incluent pas cette bibliothèque (par exemple, Android 6.0 et versions ultérieures). Pour résoudre ce problème, assurez-vous d'intégrer toutes vos bibliothèques non-NDK à votre APK.
Les applications ne doivent pas utiliser de bibliothèques natives qui ne sont pas incluses dans le NDK, car elles peuvent être modifiées ou supprimées d'une version d'Android à l'autre. Le passage d'OpenSSL à BoringSSL est un exemple de ce type de changement. De plus, comme il n'existe aucune exigence de compatibilité pour les bibliothèques de plates-formes non incluses dans le NDK, différents appareils peuvent offrir différents niveaux de compatibilité.
Afin de réduire l'impact que cette restriction peut avoir sur les applications actuellement publiées, un ensemble de bibliothèques très utilisées (comme libandroid_runtime.so, libcutils.so, libcrypto.so et libssl.so) sont temporairement accessibles sur Android 7.0 (niveau d'API 24) pour les applications ciblant le niveau d'API 23 ou une version antérieure. Si votre application charge l'une de ces bibliothèques, logcat génère un avertissement et un toast s'affiche sur l'appareil cible pour vous en informer. Si vous voyez ces avertissements, vous devez mettre à jour votre application pour inclure sa propre copie de ces bibliothèques ou n'utiliser que les API NDK publiques. Les futures versions de la plate-forme Android pourraient restreindre complètement l'utilisation des bibliothèques privées et entraîner le plantage de votre application.
Toutes les applications génèrent une erreur d'exécution lorsqu'elles appellent une API qui n'est ni publique, ni temporairement accessible. Par conséquent, System.loadLibrary et dlopen(3) renvoient tous deux NULL, ce qui peut entraîner le plantage de votre application. Vous devez examiner le code de votre application pour supprimer l'utilisation des API de plate-forme privées et tester minutieusement vos applications à l'aide d'un appareil ou d'un émulateur exécutant Android 7.0 (niveau d'API 24). Si vous ne savez pas si votre application utilise des bibliothèques privées, vous pouvez consulter logcat pour identifier l'erreur d'exécution.
Le tableau suivant décrit le comportement attendu d'une application en fonction de son utilisation de bibliothèques natives privées et de son niveau d'API cible (android:targetSdkVersion).
| Bibliothèques | Niveau d'API cible | Accès à l'environnement d'exécution à l'aide de l'éditeur de liens dynamique | Comportement d'Android 7.0 (niveau d'API 24) | Comportement futur de la plate-forme Android |
|---|---|---|---|---|
| NDK Public | Tous | Accessible | Fonctionne comme prévu | Fonctionne comme prévu |
| Privé (bibliothèques privées temporairement accessibles) | 23 ou moins | Temporairement accessible | Fonctionne comme prévu, mais vous recevez un avertissement logcat. | Erreur d'exécution |
| Privé (bibliothèques privées temporairement accessibles) | 24 ou plus | Limité | Erreur d'exécution | Erreur d'exécution |
| Privé (autre) | Tous | Limité | Erreur d'exécution | Erreur d'exécution |
Vérifier si votre application utilise des bibliothèques privées
Pour vous aider à identifier les problèmes de chargement des bibliothèques privées, logcat peut générer un avertissement ou une erreur d'exécution. Par exemple, si votre application cible le niveau d'API 23 ou une version antérieure et tente d'accéder à une bibliothèque privée sur un appareil équipé d'Android 7.0, un avertissement semblable à celui-ci peut s'afficher :
03-21 17:07:51.502 31234 31234 W linker : library "libandroid_runtime.so"
("/system/lib/libandroid_runtime.so") needed or dlopened by
"/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible
for the namespace "classloader-namespace" - the access is temporarily granted
as a workaround for http://b/26394120
Ces avertissements logcat vous indiquent quelle bibliothèque tente d'accéder à une API de plate-forme privée, mais n'entraînent pas le plantage de votre application. Toutefois, si l'application cible le niveau d'API 24 ou supérieur, logcat génère l'erreur d'exécution suivante et votre application peut planter :
java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so"
("/system/lib/libcutils.so") needed or dlopened by
"/system/lib/libnativeloader.so" is not accessible for the namespace
"classloader-namespace"
at java.lang.Runtime.loadLibrary0(Runtime.java:977)
at java.lang.System.loadLibrary(System.java:1602)
Vous pouvez également voir ces sorties logcat si votre application utilise des bibliothèques tierces qui sont liées de manière dynamique à des API de plate-forme privées. L'outil readelf du NDK Android 7.0 vous permet de générer une liste de toutes les bibliothèques partagées associées de manière dynamique d'un fichier .so donné en exécutant la commande suivante :
aarch64-linux-android-readelf -dW libMyLibrary.so
Mettez à jour votre application
Voici quelques étapes à suivre pour corriger ces types d'erreurs et vous assurer que votre application ne plante pas lors des futures mises à jour de la plate-forme :
- Si votre application utilise des bibliothèques de plate-forme privées, vous devez la mettre à jour pour inclure sa propre copie de ces bibliothèques ou utiliser les API NDK publiques.
- Si votre application utilise une bibliothèque tierce qui accède à des symboles privés, contactez l'auteur de la bibliothèque pour la mettre à jour.
- Assurez-vous d'empaqueter toutes vos bibliothèques non-NDK avec votre APK.
- Utilisez les fonctions JNI standards au lieu de
getJavaVMetgetJNIEnvdelibandroid_runtime.so:AndroidRuntime::getJavaVM -> GetJavaVM from <jni.h> AndroidRuntime::getJNIEnv -> JavaVM::GetEnv or JavaVM::AttachCurrentThread from <jni.h>.
- Utilisez
__system_property_getau lieu du symbole privéproperty_getdelibcutils.so. Pour ce faire, utilisez__system_property_getavec l'inclusion suivante :#include <sys/system_properties.h>Remarque : La disponibilité et le contenu des propriétés système ne sont pas testés via CTS. Une meilleure solution consisterait à éviter d'utiliser ces propriétés.
- Utilisez une version locale du symbole
SSL_ctrldelibcrypto.so. Par exemple, vous devez lier de manière statiquelibcyrpto.adans votre fichier.soou inclure une version delibcrypto.soliée de manière dynamique à partir de BoringSSL/OpenSSL et l'empaqueter dans votre APK.
Android for Work
Android 7.0 contient des modifications pour les applications qui ciblent Android for Work, y compris des modifications concernant l'installation des certificats, la réinitialisation du mot de passe, la gestion des utilisateurs secondaires et l'accès aux identifiants de l'appareil. Si vous créez des applications pour des environnements Android for Work, vous devez examiner ces modifications et modifier votre application en conséquence.
- Vous devez installer un programme d'installation de certificats délégués avant que le DPC puisse le définir. Pour les applications de propriétaire de profil et de propriétaire d'appareil ciblant Android 7.0 (niveau d'API 24), vous devez installer le programme d'installation de certificat délégué avant que le contrôleur de règles relatives aux appareils (DPC, Device Policy Controller) n'appelle
DevicePolicyManager.setCertInstallerPackage(). Si le programme d'installation n'est pas déjà installé, le système génère une erreurIllegalArgumentException. - Les restrictions de réinitialisation du mot de passe pour les administrateurs d'appareils s'appliquent désormais aux propriétaires de profils. Les administrateurs d'appareils ne peuvent plus utiliser
DevicePolicyManager.resetPassword()pour effacer les mots de passe ou modifier ceux qui sont déjà définis. Les administrateurs de l'appareil peuvent toujours définir un mot de passe, mais uniquement lorsque l'appareil n'a pas de mot de passe, de code ni de schéma. - Les propriétaires d'appareils et de profils peuvent gérer les comptes même si des restrictions sont définies. Les propriétaires d'appareils et de profils peuvent appeler les API Account Management même si des restrictions d'utilisateur
DISALLOW_MODIFY_ACCOUNTSsont en place. - Les propriétaires d'appareils peuvent gérer les utilisateurs secondaires. Lorsqu'un appareil est exécuté en mode propriétaire de l'appareil, la restriction
DISALLOW_ADD_USERest automatiquement définie. Cela empêche les utilisateurs de créer des utilisateurs secondaires non gérés. De plus, les méthodesCreateUser()etcreateAndInitializeUser()sont obsolètes. Elles sont remplacées par la nouvelle méthodeDevicePolicyManager.createAndManageUser(). - Les propriétaires d'appareils peuvent accéder aux identifiants des appareils. Un propriétaire d'appareil peut accéder à l'adresse MAC Wi-Fi d'un appareil à l'aide de
DevicePolicyManager.getWifiMacAddress(). Si le Wi-Fi n'a jamais été activé sur l'appareil, cette méthode renvoie la valeurnull. - Le paramètre "Mode professionnel" contrôle l'accès aux applications professionnelles. Lorsque le mode professionnel est désactivé, le lanceur d'applications du système indique que les applications professionnelles ne sont pas disponibles en les grisant. La réactivation du mode professionnel rétablit le comportement normal.
- Lors de l'installation d'un fichier PKCS #12 contenant une chaîne de certificats client et la clé privée correspondante à partir de l'interface utilisateur des paramètres, le certificat CA de la chaîne n'est plus installé dans le stockage des identifiants de confiance. Cela n'affecte pas le résultat de
KeyChain.getCertificateChain()lorsque les applications tentent de récupérer la chaîne de certificats client ultérieurement. Si nécessaire, le certificat CA doit être installé dans le stockage des identifiants de confiance à l'aide de l'UI des paramètres, au format DER avec une extension de fichier .crt ou .cer. - À partir d'Android 7.0, l'enregistrement et le stockage des empreintes digitales sont gérés par utilisateur. Si le client Device Policy (DPC) d'un propriétaire de profil cible le niveau d'API 23 (ou inférieur) sur un appareil exécutant Android 7.0 (niveau d'API 24), l'utilisateur peut toujours définir une empreinte digitale sur l'appareil, mais les applications professionnelles ne peuvent pas y accéder. Lorsque le DPC cible le niveau d'API 24 ou supérieur, l'utilisateur peut définir une empreinte digitale spécifiquement pour le profil professionnel en accédant à Paramètres > Sécurité > Sécurité du profil professionnel.
- Un nouvel état de chiffrement
ENCRYPTION_STATUS_ACTIVE_PER_USERest renvoyé parDevicePolicyManager.getStorageEncryptionStatus()pour indiquer que le chiffrement est actif et que la clé de chiffrement est associée à l'utilisateur. Le nouvel état n'est renvoyé que si le DPC cible le niveau d'API 24 ou supérieur. Pour les applications ciblant des niveaux d'API antérieurs,ENCRYPTION_STATUS_ACTIVEest renvoyé, même si la clé de chiffrement est spécifique à l'utilisateur ou au profil. - Sous Android 7.0, plusieurs méthodes qui affectent normalement l'ensemble de l'appareil se comportent différemment si l'appareil dispose d'un profil professionnel installé avec un test d'authentification professionnel distinct. Plutôt que d'affecter l'ensemble de l'appareil, ces méthodes ne s'appliquent qu'au profil professionnel. (La liste complète de ces méthodes est disponible dans la documentation de
DevicePolicyManager.getParentProfileInstance().) Par exemple,DevicePolicyManager.lockNow()ne verrouille que le profil professionnel, et non l'ensemble de l'appareil. Pour chacune de ces méthodes, vous pouvez obtenir l'ancien comportement en appelant la méthode sur l'instance parente deDevicePolicyManager. Vous pouvez obtenir ce parent en appelantDevicePolicyManager.getParentProfileInstance(). Par exemple, si vous appelez la méthodelockNow()de l'instance parente, l'appareil entier est verrouillé.
Conservation des annotations
Android 7.0 corrige un bug qui ignorait la visibilité des annotations. Ce problème permettait à l'environnement d'exécution d'accéder à des annotations auxquelles il n'aurait pas dû avoir accès. Ces annotations incluaient :
VISIBILITY_BUILD: destiné à n'être visible qu'au moment de la compilation.VISIBILITY_SYSTEM: destiné à être visible au moment de l'exécution, mais uniquement par le système sous-jacent.
Si votre application s'appuie sur ce comportement, ajoutez une règle de conservation aux annotations qui doivent être disponibles au moment de l'exécution. Pour ce faire, utilisez @Retention(RetentionPolicy.RUNTIME).
Modifications de la configuration TLS/SSL par défaut
Android 7.0 apporte les modifications suivantes à la configuration TLS/SSL par défaut utilisée par les applications pour le trafic HTTPS et d'autres trafics TLS/SSL :
- Les suites de chiffrement RC4 sont désormais désactivées.
- Les suites de chiffrement CHACHA20-POLY1305 sont désormais activées.
La désactivation de RC4 par défaut peut entraîner des interruptions de la connectivité HTTPS ou TLS/SSL lorsque le serveur ne négocie pas les suites de chiffrement modernes. La solution privilégiée consiste à améliorer la configuration du serveur pour activer des suites et des protocoles de chiffrement plus puissants et plus modernes. Idéalement, TLSv1.2 et AES-GCM doivent être activés, et les suites de chiffrement à confidentialité persistante (ECDHE) doivent être activées et privilégiées.
Vous pouvez également modifier l'application pour qu'elle utilise un SSLSocketFactory personnalisé pour communiquer avec le serveur. La fabrique doit être conçue pour créer des instances SSLSocket pour lesquelles certaines des suites de chiffrement requises par le serveur sont activées, en plus des suites de chiffrement par défaut.
Remarque : Ces modifications ne concernent pas WebView.
Applications ciblant Android 7.0
Ces changements de comportement s'appliquent exclusivement aux applications qui ciblent Android 7.0 (niveau d'API 24) ou version ultérieure. Les applications qui compilent sur Android 7.0 ou qui définissent targetSdkVersion sur Android 7.0 ou version ultérieure doivent modifier leurs applications pour qu'elles prennent en charge ces comportements, le cas échéant.
Modifications de la sérialisation
Android 7.0 (niveau d'API 24) a corrigé un bug dans le calcul du serialVersionUID par défaut, qui ne correspondait pas à la spécification.
Les classes qui implémentent Serializable et ne spécifient pas de champ serialVersionUID explicite peuvent voir leur serialVersionUID par défaut modifié, ce qui entraîne une exception lors de la tentative de désérialisation des instances de la classe qui ont été sérialisées sur une version antérieure ou par une application ciblant une version antérieure. Le message d'erreur ressemblera à ceci :
local class incompatible: stream classdesc serialVersionUID = 1234, local class serialVersionUID = 4567
Pour résoudre ces problèmes, vous devez ajouter un champ serialVersionUID à toute classe concernée avec la valeur stream classdesc
serialVersionUID du message d'erreur, par exemple 1234 dans ce cas. Cette modification respecte toutes les recommandations de bonnes pratiques pour l'écriture de code de sérialisation et fonctionnera sur toutes les versions d'Android.
Le bug spécifique qui a été corrigé était lié à la présence de méthodes d'initialisation statiques, c'est-à-dire <clinit>. Selon la spécification, la présence ou l'absence d'une méthode d'initialisation statique dans la classe affecte le serialVersionUID par défaut calculé pour cette classe.
Avant la correction de bug, le calcul vérifiait également la super-classe pour un initialiseur statique si une classe n'en avait pas.
Pour rappel, cette modification n'affecte pas les applications qui ciblent les niveaux d'API 23 ou inférieurs, les classes comportant un champ serialVersionUID ou les classes comportant une méthode d'initialisation statique.
Autres points importants
- Lorsqu'une application s'exécute sur Android 7.0, mais cible un niveau d'API inférieur, et que l'utilisateur modifie la taille d'affichage, le processus de l'application est arrêté. L'application doit pouvoir gérer ce scénario de manière appropriée. Sinon, elle plante lorsque l'utilisateur la restaure à partir de l'écran "Récents".
Vous devez tester votre application pour vous assurer que ce comportement ne se produit pas. Pour ce faire, vous pouvez provoquer un plantage identique en forçant l'arrêt de l'application manuellement à l'aide de DDMS.
Les applications ciblant Android 7.0 (niveau d'API 24) ou version ultérieure ne sont pas automatiquement arrêtées en cas de changement de densité. Toutefois, elles peuvent toujours mal réagir aux changements de configuration.
- Les applications sur Android 7.0 doivent pouvoir gérer correctement les modifications de configuration et ne doivent pas planter lors des démarrages suivants. Vous pouvez vérifier le comportement de l'application en modifiant la taille de la police (Paramètres > Affichage > Taille de la police), puis en restaurant l'application à partir de l'écran "Récents".
-
En raison d'un bug dans les versions précédentes d'Android, le système ne signalait pas l'écriture dans un socket TCP sur le thread principal comme une violation du mode strict. Android 7.0 corrige ce bug.
Les applications qui présentent ce comportement génèrent désormais une exception
android.os.NetworkOnMainThreadException. En général, effectuer des opérations réseau sur le thread principal est une mauvaise idée, car ces opérations ont généralement une latence élevée qui entraîne des erreurs ANR et des à-coups. -
La famille de méthodes
Debug.startMethodTracing()stocke désormais par défaut les résultats dans le répertoire spécifique à votre package sur l'espace de stockage partagé, et non au niveau supérieur de la carte SD. Cela signifie que les applications n'ont plus besoin de demander l'autorisationWRITE_EXTERNAL_STORAGEpour utiliser ces API. -
De nombreuses API de plate-forme ont commencé à vérifier si des charges utiles volumineuses sont envoyées via des transactions
Binder. Le système renvoie désormaisTransactionTooLargeExceptionsen tant queRuntimeExceptions, au lieu de les consigner ou de les supprimer de manière silencieuse. Par exemple, si vous stockez trop de données dansActivity.onSaveInstanceState(),ActivityThread.StopInfogénère une erreurRuntimeExceptionlorsque votre application cible Android 7.0. -
Si une application publie des tâches
Runnabledans unViewet que leViewn'est pas associé à une fenêtre, le système met en file d'attente la tâcheRunnableavec leView. La tâcheRunnablene s'exécute pas tant que leViewn'est pas associé à une fenêtre. Ce comportement corrige les bugs suivants : -
Si une application sur Android 7.0 disposant de l'autorisation
DELETE_PACKAGEStente de supprimer un package, mais qu'une autre application l'a installé, le système demande confirmation à l'utilisateur. Dans ce scénario, les applications doivent s'attendre à recevoir l'état de retourSTATUS_PENDING_USER_ACTIONlorsqu'elles appellentPackageInstaller.uninstall(). - Le fournisseur JCA appelé Crypto est obsolète, car son seul algorithme, SHA1PRNG, est faible d'un point de vue cryptographique. Les applications ne peuvent plus utiliser SHA1PRNG pour dériver des clés (de manière non sécurisée), car ce fournisseur n'est plus disponible. Pour en savoir plus, consultez l'article de blog Security "Crypto" provider deprecated in Android N (Abandon du fournisseur de sécurité "Crypto" dans Android N).