Présentation de Play Feature Delivery

Le modèle de distribution d'application de Google Play utilise des Android App Bundles pour générer et distribuer des APK optimisés pour la configuration d'appareil de chaque utilisateur. Les utilisateurs téléchargent ainsi uniquement le code et les ressources dont ils ont besoin pour exécuter votre application.

Play Feature Delivery utilise des fonctionnalités avancées d'app bundles, qui permettent de distribuer certaines fonctionnalités de votre application de manière conditionnelle ou de les télécharger à la demande. Pour ce faire, vous devez d'abord séparer ces fonctionnalités de votre application de base en modules de fonctionnalité.

Configuration de compilation du module de fonctionnalité

Lorsque vous créez un module de fonctionnalité à l'aide d'Android Studio, l'IDE applique le plug-in Gradle suivant au fichier build.gradle du module.

// The following applies the dynamic-feature plugin to your feature module.
// The plugin includes the Gradle tasks and properties required to configure and build
// an app bundle that includes your feature module.

plugins {
  id 'com.android.dynamic-feature'
}

Nombre des propriétés disponibles pour le plug-in d'application standard sont également disponibles pour votre module de fonctionnalité. Les sections suivantes décrivent les propriétés à inclure et à ne pas inclure dans la configuration de compilation de votre module de fonctionnalité.

Éléments à ne pas inclure dans la configuration de compilation du module de fonctionnalité

Étant donné que chaque module de fonctionnalité dépend du module de base, les modules de fonctionnalité héritent également de certaines configurations. Vous devez donc omettre les éléments suivants dans le fichier build.gradle du module de fonctionnalité :

  • Configurations de signature : les app bundles sont signés à l'aide des configurations de signature que vous spécifiez dans le module de base.
  • Propriété minifyEnabled : vous ne pouvez activer la minification de code pour l'ensemble de votre projet d'application qu'à partir de la configuration de compilation du module de base. Vous devez donc omettre cette propriété dans les modules de fonctionnalité. Toutefois, vous pouvez spécifier des règles ProGuard supplémentaires pour chaque module de fonctionnalité.
  • versionCode et versionName lors de la création de votre app bundle, Gradle utilise les informations sur la version de l'application fournies par le module de base. Vous devez omettre ces propriétés dans le fichier build.gradle de votre module de fonctionnalité.

Établir une relation avec le module de base

Après avoir créé votre module de fonctionnalité, Android Studio le rend visible par le module de base en ajoutant la propriété android.dynamicFeatures au fichier build.gradle du module de base, comme indiqué ci-dessous :

// In the base module’s build.gradle file.
android {
    ...
    // Specifies feature modules that have a dependency on
    // this base module.
    dynamicFeatures = [":dynamic_feature", ":dynamic_feature2"]
}

De plus, Android Studio inclut le module de base en tant que dépendance du module de fonctionnalité, comme indiqué ci-dessous :

// In the feature module’s build.gradle file:
...
dependencies {
    ...
    // Declares a dependency on the base module, ':app'.
    implementation project(':app')
}

Spécifier des règles ProGuard supplémentaires

Bien que seule la configuration de compilation du module de base permette la minification du code pour votre projet d'application, vous pouvez fournir des règles ProGuard personnalisées avec chaque module de fonctionnalité à l'aide de proguardFiles, comme indiqué ci-dessous.

android.buildTypes {
     release {
         // You must use the following property to specify additional ProGuard
         // rules for feature modules.
         proguardFiles 'proguard-rules-dynamic-features.pro'
     }
}

Notez que ces règles ProGuard sont fusionnées avec celles d'autres modules (y compris le module de base) au moment de la compilation. Ainsi, bien que chaque module de fonctionnalité puisse spécifier un nouvel ensemble de règles, ces règles s'appliquent à tous les modules du projet d'application.

Déployer votre application

Lorsque vous développez une application avec prise en charge des modules de fonctionnalités, vous pouvez la déployer sur un appareil connecté comme vous le feriez normalement en sélectionnant Exécuter > Exécuter dans la barre de menu, ou en cliquant sur Exécuter  dans la barre d'outils.

Si votre projet d'application inclut un ou plusieurs modules de fonctionnalité, vous pouvez choisir les fonctionnalités à inclure lors du déploiement de votre application en modifiant votre configuration d'exécution/de débogage existante comme suit :

  1. Sélectionnez Exécuter > Modifier les configurations dans la barre de menu.
  2. Dans le panneau de gauche de la boîte de dialogue Configurations d'exécution/de débogage, sélectionnez la configuration d'application Android souhaitée.
  3. Sous Fonctionnalités dynamiques à déployer dans l'onglet Général, cochez la case située à côté de chaque module de fonctionnalité que vous souhaitez inclure lors du déploiement de votre application.
  4. Cliquez sur OK.

Par défaut, Android Studio n'utilise pas d'app bundles pour déployer votre application. L'IDE crée et installe sur votre appareil des APK optimisés pour leur vitesse de déploiement, plutôt que pour leur taille. Pour configurer Android Studio afin qu'il crée et déploie plutôt des APK et des expériences instantanées à partir d'un app bundle, modifiez votre configuration d'exécution/de débogage.

Utiliser des modules de fonctionnalité pour une distribution personnalisée

L'un des avantages uniques des modules de fonctionnalité est la possibilité de personnaliser quand et comment différentes fonctionnalités de votre application sont téléchargées sur des appareils équipés d'Android 5.0 (niveau d'API 21) ou version ultérieure. Pour réduire la taille de téléchargement initiale de votre application, vous pouvez configurer certaines fonctionnalités de sorte qu'elles puissent être téléchargées à la demande ou seulement sur les appareils compatibles. Par exemple, la capacité de prendre des photos ou la prise en charge de fonctionnalités de réalité augmentée.

Bien que les téléchargements soient hautement optimisés par défaut lorsque vous importez votre application en tant qu'app bundle, les options de distribution de fonctionnalités plus avancées et personnalisables nécessitent une configuration et une modularisation supplémentaires des fonctionnalités de votre application à l'aide de modules de fonctionnalité. Autrement dit, les modules de fonctionnalité fournissent des composants pour la création de fonctionnalités modulaires que vous pouvez configurer pour qu'elles puissent être téléchargées en fonction des besoins.

Prenons l'exemple d'une application qui permet à vos utilisateurs d'acheter et de vendre des produits sur une place de marché en ligne. Vous pouvez raisonnablement modulariser chacune des fonctionnalités suivantes de l'application dans des modules de fonctionnalité distincts :

  • Connexion et création de compte
  • Navigation dans la place de marché
  • Mise en vente d'un article
  • Traitement des paiements

Le tableau ci-dessous décrit les différentes options de distribution compatibles avec les modules de fonctionnalité, et explique comment elles peuvent permettre d'optimiser la taille de téléchargement initiale de l'exemple d'application de place de marché.

Option de distribution Comportement Exemple de cas d'utilisation Premiers pas
Distribution au moment de l'installation Les modules de fonctionnalité qui ne configurent aucune des options de distribution décrites ci-dessus sont téléchargés par défaut lors de l'installation de l'application. Il s'agit d'un comportement important, car cela signifie que vous pouvez adopter progressivement des options de distribution avancées. Par exemple, vous pouvez bénéficier de la modularisation des fonctionnalités de votre application et activer la distribution à la demande uniquement après avoir complètement implémenté les téléchargements à la demande à l'aide de la bibliothèque Play Feature Delivery.

De plus, votre application peut demander à désinstaller des fonctionnalités ultérieurement. Ainsi, si vous avez besoin de certaines fonctionnalités lors de l'installation de l'application, mais pas après, vous pouvez réduire la taille d'installation en demandant à supprimer la fonctionnalité de l'appareil.

Si l'application propose certaines activités de formation, telles qu'un guide interactif sur l'achat et la vente d'articles sur la place de marché, vous pouvez inclure cette fonctionnalité lors de l'installation de l'application, par défaut.

Toutefois, pour réduire la taille d'installation de l'application, celle-ci peut demander la suppression de la fonctionnalité une fois l'utilisateur formé.

Modularisez votre application à l'aide de modules de fonctionnalité qui ne configurent aucune option de distribution avancée.

Pour savoir comment réduire la taille d'installation de votre application en supprimant certains modules de fonctionnalité dont l'utilisateur n'a plus besoin, consultez la section Gérer les modules installés.

Distribution à la demande Permet à votre application de demander et de télécharger des modules de fonctionnalité selon les besoins. Si seulement 20 % des utilisateurs de l'application de place de marché mettent des articles en vente, une bonne stratégie pour réduire la taille de téléchargement initiale pour la majorité des utilisateurs consiste à proposer des fonctionnalités permettant de prendre des photos, d'inclure la description d'un article et de mettre un article en vente, sous la forme d'un téléchargement à la demande. Autrement dit, vous pouvez configurer le module de fonctionnalité pour que la fonctionnalité de vente de l'application ne soit téléchargée que lorsqu'un utilisateur souhaite mettre des articles en vente sur la place de marché.

Par ailleurs, si l'utilisateur ne vend plus d'articles après une certaine période, l'application peut réduire la taille d'installation en demandant la désinstallation de la fonctionnalité.

Créez un module de fonctionnalité et configurez la distribution à la demande. Votre application peut ensuite utiliser la bibliothèque Play Feature Delivery pour demander le téléchargement du module à la demande.
Distribution conditionnelle Permet de spécifier certaines exigences relatives aux appareils des utilisateurs, telles que des fonctionnalités matérielles, des paramètres régionaux et un niveau d'API minimal, afin de déterminer si une fonctionnalité modularisée est téléchargée lors de l'installation de l'application. Si l'application de place de marché est présente dans le monde entier, vous devrez peut-être accepter des modes de paiement qui sont courants uniquement dans certaines régions ou certains pays. Afin de réduire la taille de téléchargement initiale de l'application, vous pouvez créer des modules de fonctionnalité distincts pour traiter certains types de modes de paiement et les installer de manière conditionnelle sur l'appareil de l'utilisateur, en fonction des paramètres régionaux enregistrés. Créez un module de fonctionnalité et configurez la distribution conditionnelle
Distribution instantanée Google Play Instant permet aux utilisateurs d'interagir avec votre application sans avoir à l'installer sur leur appareil. Ils peuvent ainsi accéder à votre application via le bouton "Essayer" du Google Play Store ou via une URL que vous avez créée. Cette méthode de distribution de contenu vous permet d'accroître plus facilement l'engagement des utilisateurs avec votre application.

Avec la distribution instantanée, vous pouvez utiliser Google Play Instant pour permettre à vos utilisateurs de profiter instantanément de certaines fonctionnalités de votre application sans installation.

Imaginez un jeu qui inclut ses premiers niveaux dans un module de fonctionnalité léger. Vous pouvez permettre une utilisation instantanée de ce module afin que les utilisateurs puissent profiter instantanément du jeu via un lien URL ou le bouton "Essayer", et ce sans installer l'application. Créez un module de fonctionnalité et configurez la distribution instantanée. Votre application peut ensuite utiliser la bibliothèque Play Feature Delivery pour demander le téléchargement du module à la demande.

N'oubliez pas que la modularisation des fonctionnalités de votre application à l'aide de modules de fonctionnalité n'est que la première étape. Pour être compatible avec Google Play Instant, la taille de téléchargement du module de base de votre application et d'une fonctionnalité donnée permettant une utilisation instantanée doit respecter des restrictions de taille strictes. Pour en savoir plus, consultez Activer les expériences instantanées en réduisant la taille de l'application ou du jeu.

Créer un URI pour une ressource

Si vous souhaitez accéder à une ressource stockée dans un module de fonctionnalité à l'aide d'un URI, voici comment générer un URI de ressource de module de fonctionnalité à l'aide de Uri.Builder() :

Kotlin

val uri = Uri.Builder()
                .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
                .authority(context.getPackageName()) // Look up the resources in the application with its splits loaded
                .appendPath(resources.getResourceTypeName(resId))
                .appendPath(String.format("%s:%s",
                  resources.getResourcePackageName(resId), // Look up the dynamic resource in the split namespace.
                  resources.getResourceEntryName(resId)
                  ))
                .build()

Java

String uri = Uri.Builder()
                .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
                .authority(context.getPackageName()) // Look up the resources in the application with its splits loaded
                .appendPath(resources.getResourceTypeName(resId))
                .appendPath(String.format("%s:%s",
                  resources.getResourcePackageName(resId), // Look up the dynamic resource in the split namespace.
                  resources.getResourceEntryName(resId)
                  ))
                .build().toString();

Chaque partie du chemin d'accès à la ressource est construite au moment de l'exécution, ce qui garantit que l'espace de noms approprié est généré après le chargement des APK divisés.

Pour un exemple de la manière dont l'URI est généré, imaginons que vous disposez d'une application et de modules de fonctionnalité portant les noms suivants :

  • Nom du package d'application : com.example.my_app_package
  • Nom du package de ressources de la fonctionnalité : com.example.my_app_package.my_dynamic_feature

Si l'élément resId de l'extrait de code ci-dessus fait référence à une ressource de fichier brute nommée "my_video" dans votre module de fonctionnalité, le code Uri.Builder() ci-dessus génère le résultat suivant :

android.resource://com.example.my_app_package/raw/com.example.my_app_package.my_dynamic_feature:my_video

Votre application peut ensuite utiliser cet URI pour accéder à la ressource du module de fonctionnalité.

Pour valider les chemins dans votre URI, vous pouvez utiliser l'analyseur d'APK pour inspecter l'APK du module de fonctionnalité et déterminer le nom du package :

Capture d'écran de l'analyseur d'APK qui inspecte le contenu d'un fichier de ressources compilé.
Figure 1 : Utilisez l'analyseur d'APK pour inspecter le nom du package dans un fichier de ressources compilé.

Remarques concernant les modules de fonctionnalité

Les modules de fonctionnalité vous permettent d'améliorer la vitesse de compilation et d'ingénierie, et de personnaliser de manière significative la distribution des fonctionnalités de votre application afin de réduire sa taille. Toutefois, vous devez tenir compte de certaines contraintes et de certains cas particuliers lorsque vous utilisez des modules de fonctionnalité :

  • L'installation de 50 modules de fonctionnalité ou plus sur un seul appareil via une distribution conditionnelle ou à la demande peut entraîner des problèmes de performances. Les modules d'installation de l'application, qui ne sont pas configurés comme pouvant être supprimés, sont automatiquement inclus dans le module de base et ne comptent que pour un module de fonctionnalité sur chaque appareil.
  • Limitez le nombre de modules que vous configurez comme pouvant être supprimés pour la distribution au moment de l'installation à 10 ou moins. Sinon, le temps de téléchargement et d'installation de votre application peut augmenter.
  • Seuls les appareils équipés d'Android 5.0 (niveau d'API 21) ou version ultérieure sont compatibles avec le téléchargement et l'installation de fonctionnalités à la demande. Pour rendre votre fonctionnalité disponible dans les versions antérieures d'Android, activez Fusing lorsque vous créez un module de fonctionnalité.
  • Activez SplitCompat afin que votre application ait accès aux modules de fonctionnalité téléchargés et distribués à la demande.
  • Les modules de fonctionnalité ne doivent pas spécifier d'activités dans leur fichier manifeste lorsque android:exported est défini sur true. En effet, rien ne garantit que l'appareil a téléchargé le module de fonctionnalité lorsqu'une autre application tente de lancer l'activité. Par ailleurs, votre application doit confirmer qu'une fonctionnalité a été téléchargée avant d'essayer d'accéder à son code et à ses ressources. Pour en savoir plus, consultez la section Gérer les modules installés.
  • Comme Play Feature Delivery nécessite de publier votre application à l'aide d'un app bundle, assurez-vous de connaître les problèmes connus avec les app bundle.

Référence du fichier manifeste du module de fonctionnalité

Lors de la création d'un module de fonctionnalité à l'aide d'Android Studio, l'IDE inclut la plupart des attributs de manifeste dont le module a besoin pour se comporter comme un module de fonctionnalité. De plus, certains attributs sont injectés par le système de compilation au moment de la compilation. Vous n'avez donc pas besoin de les spécifier ni de les modifier vous-même. Le tableau suivant décrit les attributs de fichier manifeste qui sont importants pour les modules de fonctionnalité.

Attribut Description
<manifest Il s'agit d'un bloc <manifest> typique.
xmlns:dist="http://schemas.android.com/apk/distribution" Spécifie un nouvel espace de noms XML dist: décrit plus loin.
split="split_name" Lors de la création de votre app bundle, Android Studio inclut cet attribut pour vous. Par conséquent, vous ne devez pas inclure ni modifier cet attribut vous-même.

Définit le nom du module, spécifié par votre application lors de la demande d'un module à la demande à l'aide de la bibliothèque Play Feature Delivery.

Comment Gradle détermine la valeur de cet attribut :

Par défaut, lorsque vous créez un module de fonctionnalité à l'aide d'Android Studio, l'IDE utilise ce que vous spécifiez en tant que nom de module pour identifier le module en tant que sous-projet Gradle dans votre Fichier de paramètres Gradle.

Lorsque vous créez votre app bundle, Gradle utilise le dernier élément du chemin d'accès du sous-projet pour injecter cet attribut de fichier manifeste dans le fichier manifeste du module. Par exemple, si vous créez un module de fonctionnalité dans le répertoire MyAppProject/features/ et avez spécifié "dynamic_feature1" comme nom de module, l'IDE ajoute ':features:dynamic_feature1' en tant que sous-projet dans votre fichier settings.gradle. Lors de la compilation de votre app bundle, Gradle injecte ensuite <manifest split="dynamic_feature1"> dans le fichier manifeste du module.

android:isFeatureSplit="true | false"> Lors de la création de votre app bundle, Android Studio inclut cet attribut pour vous. Par conséquent, vous ne devez pas inclure ni modifier cet attribut manuellement.

Indique que ce module est un module de fonctionnalité. Les fichiers manifeste dans le module de base et les APK de configuration omettent cet attribut ou le définissent sur false.

<dist:module Définit les attributs qui déterminent la façon dont le module est empaqueté et distribué sous forme d'APK.
dist:instant="true | false" Indique si le module doit être disponible via Google Play Instant en tant qu'expérience instantanée.

Si votre application inclut un ou plusieurs modules de fonctionnalité permettant une utilisation instantanée, vous devez également activer l'utilisation instantanée pour le module de base. Avec Android Studio 3.5 ou version ultérieure, l'IDE le fait pour vous lorsque vous créez un module de fonctionnalité permettant une utilisation instantanée.

Vous ne pouvez pas définir cet élément XML sur true tout en définissant <dist:on-demand/>. Toutefois, vous pouvez toujours demander des téléchargements à la demande de vos modules de fonctionnalité permettant une utilisation instantanée en tant qu'expériences instantanées à l'aide de la bibliothèque Play Feature Delivery. Lorsqu'un utilisateur télécharge et installe votre application, l'appareil télécharge et installe par défaut les modules de fonctionnalité permettant une utilisation instantanée de votre application, ainsi que l'APK de base.

dist:title="@string/feature_name"> Spécifie un titre destiné aux utilisateurs pour le module. Par exemple, l'appareil peut afficher ce titre lorsqu'il demande une confirmation de téléchargement.

Vous devez inclure la ressource de chaîne de ce titre dans le fichier module_root/src/source_set/res/values/strings.xml du module de base.

<dist:fusing dist:include="true | false" /> Indique si le module doit être inclus dans des APK multiples ciblant les appareils équipés d'Android 4.4 (niveau d'API 20) ou version antérieure.

De plus, lorsque vous utilisez bundletool pour générer des APK à partir d'un app bundle, seuls les modules de fonctionnalité qui définissent cette propriété sur true sont inclus dans le fichier universel APK : un fichier APK monolithique qui inclut le code et les ressources pour toutes les configurations d'appareil compatibles avec votre application

<dist:delivery> Encapsule les options permettant de personnaliser la distribution des modules, comme indiqué ci-dessous. N'oubliez pas que chaque module de fonctionnalité ne doit configurer qu'un seul type de ces options de distribution personnalisées.
<dist:install-time> Indique que le module doit être disponible au moment de l'installation. Il s'agit du comportement par défaut des modules de fonctionnalité qui ne spécifient pas un autre type d'option de distribution personnalisée.

Pour en savoir plus sur les téléchargements au moment de l'installation, consultez Configurer la distribution lors de l'installation.

Ce nœud peut également spécifier des conditions qui limitent le module aux appareils répondant à certaines exigences, telles que les fonctionnalités de l'appareil, le pays de l'utilisateur ou le niveau d'API minimal. Pour en savoir plus, consultez Configurer la distribution conditionnelle.

<dist:removable dist:value="true | false" />

Si cette règle n'est pas configurée ou qu'elle est définie sur false, bundletool fusionne les modules d'installation dans le module de base lors de la génération des APK divisés à partir du bundle. Comme la fusion entraîne moins d'APK divisés, ce paramètre peut améliorer les performances de votre application.

Lorsque removable est défini sur true, les modules d'installation ne sont pas fusionnés avec le module de base. Définissez la valeur sur true si vous souhaitez désinstaller des modules à l'avenir. Toutefois, la configuration d'un trop grand nombre de modules pouvant être supprimés peut augmenter le temps d'installation de votre application.

La valeur par défaut est false. Il n'est nécessaire de définir cette valeur dans le fichier manifeste que si vous souhaitez désactiver la fusion pour un module de fonctionnalité.

Remarque : Cette fonctionnalité n'est disponible que si vous utilisez le plug-in Android Gradle 4.2 ou si vous utilisez bundletool v1.0 depuis la ligne de commande.

</dist:install-time>  
<dist:on-demand /> Indique que le module doit être disponible en téléchargement à la demande. Autrement dit, le module n'est pas disponible au moment de l'installation, mais votre application peut demander à le télécharger plus tard.

Pour en savoir plus sur les téléchargements à la demande, consultez la page Configurer la distribution à la demande.

</dist:delivery>
</dist:module>
<application
android:hasCode="true | false">
...
</application>
Si le module de fonctionnalité ne génère pas de fichiers DEX, c'est-à-dire s'il ne contient aucun code compilé ultérieurement au format de fichier DEX, vous devez effectuer les opérations suivantes (sinon, vous risquez d'obtenir des erreurs d'exécution) :
  1. Définissez android:hasCode sur "false" dans le fichier manifeste du module de fonctionnalité.
  2. Ajoutez les éléments suivants au fichier manifeste de votre module de base :
    <application
      android:hasCode="true"
      tools:replace="android:hasCode">
      ...
    </application>
...
</manifest>

Ressources supplémentaires

Pour en savoir plus sur l'utilisation des modules de fonctionnalité, consultez les ressources suivantes.

Articles de blog

Vidéos

Conditions d'utilisation et sécurité des données

En accédant à la bibliothèque Play Feature Delivery ou en l'utilisant, vous acceptez les Conditions d'utilisation du kit de développement logiciel Play Core. Lisez attentivement les règles et conditions d'utilisation applicables avant d'accéder à la bibliothèque.

Sécurité des données

Les bibliothèques Play Core constituent l'interface d'exécution de votre application avec le Google Play Store. Ainsi, lorsque vous utilisez Play Core dans votre application, le Play Store exécute ses propres processus, y compris le traitement des données conformément aux Conditions d'utilisation de Google Play. Les informations ci-dessous décrivent comment les bibliothèques Play Core traitent les données pour traiter des requêtes spécifiques de votre application.

API de langues supplémentaires

Collecte des données sur l'utilisation Liste des langues installées
Rôle de la collecte de données Les données collectées sont utilisées pour fournir différentes versions linguistiques de l'application et conserver les langues installées après la mise à jour d'une application.
Chiffrement des données Les données sont chiffrées.
Partage des données Les données ne sont pas transférées à des tiers.
Suppression des données Les données sont supprimées après une durée de conservation déterminée à l'avance.

Play Feature Delivery

Collecte des données sur l'utilisation Métadonnées de l'appareil
Version de l'application
Rôle de la collecte de données Les données collectées sont utilisées pour distribuer le module approprié sur l'appareil et pour conserver les modules installés après une mise à jour, une sauvegarde et une restauration.
Chiffrement des données Les données sont chiffrées.
Partage des données Les données ne sont pas transférées à des tiers.
Suppression des données Les données sont supprimées après une durée de conservation déterminée à l'avance.

Notre objectif est d'être les plus transparents possible. Toutefois, vous êtes seul responsable de vos réponses au formulaire de Google Play pour la section Sécurité des données concernant la collecte et le partage des données utilisateur dans votre application, ainsi que vos pratiques de sécurité.