Démarrage de l'application Fait partie d'Android Jetpack.

La bibliothèque App Startup offre un moyen simple et performant d'initialiser des composants au démarrage de l'application. Les développeurs de bibliothèques et d'applications peuvent utiliser App Startup pour simplifier les séquences de démarrage et définir explicitement l'ordre d'initialisation.

Au lieu de définir des fournisseurs de contenu distincts pour chaque composant à initialiser, le démarrage d'application vous permet de définir des initialiseurs de composants qui partagent un seul fournisseur de contenu. Cela peut considérablement améliorer le temps de démarrage de l'application.

Configurer

Pour utiliser Jetpack Startup dans votre bibliothèque ou votre application, ajoutez les éléments suivants à votre fichier Gradle:

Groovy

dependencies {
    implementation "androidx.startup:startup-runtime:1.1.1"
}

Kotlin

dependencies {
    implementation("androidx.startup:startup-runtime:1.1.1")
}

Initialiser les composants au démarrage de l'application

Les applications et les bibliothèques reposent souvent sur l'initialisation immédiate des composants au démarrage de l'application. Vous pouvez répondre à ce besoin en utilisant des fournisseurs de contenu pour initialiser chaque dépendance. Toutefois, les fournisseurs de contenu sont coûteux à instancier et peuvent ralentir inutilement la séquence de démarrage. De plus, Android initialise les fournisseurs de contenu dans un ordre indéterminé. Le démarrage de l'application offre un moyen plus performant d'initialiser des composants au démarrage de l'application et de définir explicitement leurs dépendances.

Pour utiliser le démarrage de l'application afin d'initialiser automatiquement les composants au démarrage, vous devez définir un initialiseur de composant pour chaque composant que l'application doit initialiser.

Implémenter des initialiseurs de composants

Pour définir chaque initialiseur de composant, créez une classe qui implémente l'interface Initializer<T>. Cette interface définit deux méthodes importantes:

  • La méthode create(), qui contient toutes les opérations nécessaires pour initialiser le composant et renvoie une instance de T.
  • La méthode dependencies(), qui renvoie la liste des autres objets Initializer<T> dont dépend l'initialiseur. Vous pouvez utiliser cette méthode pour contrôler l'ordre dans lequel l'application exécute les initialiseurs au démarrage.

Par exemple, supposons que votre application dépend de WorkManager et qu'elle doive l'initialiser au démarrage. Définissez une classe WorkManagerInitializer qui implémente Initializer<WorkManager>:

Kotlin

// Initializes WorkManager.
class WorkManagerInitializer : Initializer<WorkManager> {
    override fun create(context: Context): WorkManager {
        val configuration = Configuration.Builder().build()
        WorkManager.initialize(context, configuration)
        return WorkManager.getInstance(context)
    }
    override fun dependencies(): List<Class<out Initializer<*>>> {
        // No dependencies on other libraries.
        return emptyList()
    }
}

Java

// Initializes WorkManager.
class WorkManagerInitializer implements Initializer<WorkManager> {

    @Override
    public WorkManager create(Context context) {
        Configuration configuration = Configuration.Builder().build();
        WorkManager.initialize(context, configuration);
        return WorkManager.getInstance(context);
    }

    @Override
    public List<Class<Initializer<?>>> dependencies() {
        // No dependencies on other libraries.
        return emptyList();
    }

}

La méthode dependencies() renvoie une liste vide, car WorkManager ne dépend d'aucune autre bibliothèque.

Supposons que votre application dépend également d'une bibliothèque appelée ExampleLogger, qui à son tour dépend de WorkManager. Cette dépendance signifie que vous devez d'abord vous assurer que le démarrage de l'application initialise WorkManager. Définissez une classe ExampleLoggerInitializer qui implémente Initializer<ExampleLogger>:

Kotlin

// Initializes ExampleLogger.
class ExampleLoggerInitializer : Initializer<ExampleLogger> {
    override fun create(context: Context): ExampleLogger {
        // WorkManager.getInstance() is non-null only after
        // WorkManager is initialized.
        return ExampleLogger(WorkManager.getInstance(context))
    }

    override fun dependencies(): List<Class<out Initializer<*>>> {
        // Defines a dependency on WorkManagerInitializer so it can be
        // initialized after WorkManager is initialized.
        return listOf(WorkManagerInitializer::class.java)
    }
}

Java

// Initializes ExampleLogger.
class ExampleLoggerInitializer implements Initializer<ExampleLogger> {

    @Override
    public ExampleLogger create(Context context) {
        // WorkManager.getInstance() is non-null only after
        // WorkManager is initialized.
        return ExampleLogger(WorkManager.getInstance(context));
    }

    @Override
    public List<Class<Initializer<?>>> dependencies() {
        // Defines a dependency on WorkManagerInitializer so it can be
        // initialized after WorkManager is initialized.
        return Arrays.asList(WorkManagerInitializer.class);
    }
}

Comme vous incluez WorkManagerInitializer dans la méthode dependencies(), le démarrage de l'application initialise WorkManager avant ExampleLogger.

Configurer des entrées du fichier manifeste

Le démarrage de l'application inclut un fournisseur de contenu spécial appelé InitializationProvider qu'il utilise pour détecter et appeler vos initialiseurs de composants. Le démarrage de l'application détecte les initialiseurs de composants en recherchant d'abord une entrée <meta-data> sous l'entrée du fichier manifeste InitializationProvider. Ensuite, le démarrage de l'application appelle les méthodes dependencies() pour tous les initialiseurs déjà détectés.

Cela signifie que pour qu'un initialiseur de composant soit visible par le démarrage d'application, l'une des conditions suivantes doit être remplie:

  • L'initialiseur du composant possède une entrée <meta-data> correspondante sous l'entrée du fichier manifeste InitializationProvider.
  • L'initialiseur de composant est répertorié dans la méthode dependencies() à partir d'un initialiseur déjà détectable.

Reprenons l'exemple avec WorkManagerInitializer et ExampleLoggerInitializer. Pour vous assurer que le démarrage de l'application peut détecter ces initialiseurs, ajoutez les éléments suivants au fichier manifeste:

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    android:exported="false"
    tools:node="merge">
    <!-- This entry makes ExampleLoggerInitializer discoverable. -->
    <meta-data  android:name="com.example.ExampleLoggerInitializer"
          android:value="androidx.startup" />
</provider>

Vous n'avez pas besoin d'ajouter une entrée <meta-data> pour WorkManagerInitializer, car WorkManagerInitializer est une dépendance de ExampleLoggerInitializer. Cela signifie que si ExampleLoggerInitializer est visible, WorkManagerInitializer l'est aussi.

L'attribut tools:node="merge" garantit que l'outil de fusion des fichiers manifestes résout correctement les entrées en conflit.

Exécuter des vérifications lint

La bibliothèque App Startup comprend un ensemble de règles lint que vous pouvez utiliser pour vérifier si vous avez correctement défini les initialiseurs de composants. Vous pouvez effectuer ces vérifications lint en exécutant ./gradlew :app:lintDebug à partir de la ligne de commande.

Initialiser manuellement les composants

Habituellement, lorsque vous utilisez le démarrage de l'application, l'objet InitializationProvider utilise une entité appelée AppInitializer pour détecter et exécuter automatiquement les initialiseurs de composants au démarrage de l'application. Toutefois, vous pouvez également utiliser directement AppInitializer afin d'initialiser manuellement les composants dont votre application n'a pas besoin au démarrage. C'est ce qu'on appelle l'initialisation différée, et elle peut aider à minimiser les coûts de démarrage.

Vous devez d'abord désactiver l'initialisation automatique pour tous les composants que vous souhaitez initialiser manuellement.

Désactiver l'initialisation automatique pour un composant individuel

Pour désactiver l'initialisation automatique d'un seul composant, supprimez l'entrée <meta-data> de l'initialiseur de ce composant dans le fichier manifeste.

Par exemple, l'ajout du code suivant au fichier manifeste désactive l'initialisation automatique pour ExampleLogger:

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    android:exported="false"
    tools:node="merge">
    <meta-data android:name="com.example.ExampleLoggerInitializer"
              tools:node="remove" />
</provider>

Utilisez tools:node="remove" dans l'entrée au lieu de simplement la supprimer afin de vous assurer que l'outil de fusion supprime également l'entrée de tous les autres fichiers manifestes fusionnés.

Désactiver l'initialisation automatique pour tous les composants

Pour désactiver l'initialisation automatique, supprimez l'intégralité de l'entrée InitializationProvider du fichier manifeste:

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    tools:node="remove" />

Appeler manuellement des initialiseurs de composants

Si l'initialisation automatique est désactivée pour un composant, vous pouvez utiliser AppInitializer pour l'initialiser manuellement et ses dépendances.

Par exemple, le code suivant appelle AppInitializer et initialise manuellement ExampleLogger:

Kotlin

AppInitializer.getInstance(context)
    .initializeComponent(ExampleLoggerInitializer::class.java)

Java

AppInitializer.getInstance(context)
    .initializeComponent(ExampleLoggerInitializer.class);

Par conséquent, le démarrage de l'application initialise également WorkManager, car WorkManager est une dépendance de ExampleLogger.

Envoyer un commentaire

Faites-nous part de vos commentaires et de vos idées via les ressources suivantes :

Issue Tracker
Signalez les problèmes pour que nous puissions corriger les bugs.