Temps de démarrage de l'application

Les utilisateurs s'attendent à ce que les applications se chargent rapidement et soient réactives. Une application dont le démarrage est lent ne répond pas à cette attente et peut décevoir les utilisateurs. Cette mauvaise expérience peut conduire l'utilisateur à donner une mauvaise note à votre application sur le Play Store, voire à l'abandonner complètement.

Cette page fournit des informations pour vous aider à optimiser le délai de démarrage de votre application. Elle offre un aperçu des mécanismes internes du processus de lancement, explique comment profiler les performances de démarrage et présente certains problèmes courants de démarrage, ainsi que des conseils pour y remédier.

Comprendre les différents états de démarrage de l'application

Le lancement d'une application peut avoir l'un des trois états suivants : démarrage à froid, démarrage tiède ou démarrage à chaud. Chaque état a une incidence sur le délai nécessaire pour que votre application soit visible par l'utilisateur. À froid, votre application part de zéro. Dans les autres états, le système doit faire passer l'application en cours d'exécution de l'arrière-plan au premier plan.

Nous vous recommandons de toujours optimiser votre application comme si elle démarrait d'office à froid. Cela peut également améliorer les performances des démarrages tiède et à chaud.

Pour optimiser votre application afin qu'elle démarre rapidement, il est utile de comprendre ce qui se passe au niveau du système et de l'application, ainsi que la façon dont ils interagissent, dans chacun de ces états.

Le délai d'affichage initial (TTID) et le délai d'affichage complet (TTFD) sont deux métriques importantes pour déterminer le démarrage de l'application. Le TTID correspond au temps nécessaire pour afficher le premier frame et le TTFD correspond au délai nécessaire pour que l'application devienne entièrement interactive. Les deux sont tout aussi importants, car le TTID indique à l'utilisateur que l'application est en cours de chargement, et le TTFD indique à quel moment l'application est réellement utilisable. Si l'un de ces délais est trop long, l'utilisateur peut quitter l'application avant même qu'elle ne soit complètement chargée.

Démarrage à froid

Le terme "démarrage à froid" désigne le démarrage d'une application à partir de zéro. Cela signifie que jusqu'au démarrage, le processus du système crée le processus de l'application. Les démarrages à froid se produisent dans les cas où votre application se lance pour la première fois depuis le démarrage de l'appareil ou lorsque le système a arrêté l'application.

Ce type de démarrage représente le plus grand défi pour réduire le délai de démarrage, car le système et l'application ont alors davantage de travail par rapport aux autres états de lancement.

Au début d'un démarrage à froid, le système doit effectuer les trois tâches suivantes :

  1. Charger et lancer l'application.
  2. Afficher une fenêtre de démarrage vide pour l'application immédiatement après le lancement.
  3. Créer le processus d'application.

Dès que le système a créé le processus d'application, ce processus est responsable des étapes suivantes :

  1. Créer l'objet d'application.
  2. Lancer le thread principal.
  3. Créer l'activité principale.
  4. Gonfler les vues.
  5. Mettre en page l'écran.
  6. Effectuer la visualisation initiale.

Une fois la première visualisation terminée, le processus système remplace la fenêtre d'arrière-plan affichée par l'activité principale. L'utilisateur peut alors commencer à utiliser l'application.

La figure 1 montre comment les processus du système et de l'application se passent la main.

Figure 1. Représentation visuelle des éléments importants du lancement à froid d'une application.

Des problèmes de performances peuvent survenir au moment où l'application et l'activité sont créées.

Création d'applications

Lorsque l'application est lancée, la fenêtre de démarrage vide reste affichée jusqu'à ce que le système ait fini d'afficher l'application. À ce stade, le processus système remplace la fenêtre de démarrage de votre application, ce qui permet à l'utilisateur d'interagir avec elle.

Si vous remplacez Application.onCreate() dans votre propre application, le système appelle la méthode onCreate() sur votre objet d'application. Par la suite, l'application génère le thread principal, également appelé thread UI, et le charge de créer votre activité principale.

À ce stade, les processus au niveau du système et de l'application se déroulent conformément aux étapes du cycle de vie de l'application.

Création de l'activité

Une fois que le processus de l'application a créé votre activité, celle-ci effectue les opérations suivantes :

  1. Initialisation des valeurs
  2. Appel des constructeurs
  3. Appel à la méthode de rappel, telle que Activity.onCreate(), adaptée à l'état du cycle de vie actuel de l'activité

En général, la méthode onCreate() a l'impact le plus élevé sur le temps de chargement, car elle effectue les tâches dont la surcharge est la plus élevée : charger et gonfler les vues, et initialiser les objets nécessaires à l'exécution de l'activité.

Démarrage tiède

Un démarrage tiède englobe un sous-ensemble des opérations qui ont lieu lors d'un démarrage à froid. Pour autant, ce sous-ensemble représente une surcharge plus importante que celle d'un démarrage à chaud. De nombreux états potentiels peuvent être considérés comme des démarrages tièdes, par exemple :

  • L'utilisateur quitte votre appli, puis la redémarre. Le processus peut continuer à s'exécuter, mais l'application doit recréer l'activité à partir de zéro à l'aide d'un appel à onCreate().

  • Le système évince votre application de la mémoire, puis l'utilisateur la relance. Le processus et l'activité doivent redémarrer, mais la tâche peut bénéficier du groupe d'états d'instances enregistrés transmis à onCreate().

Démarrage à chaud

Un démarrage à chaud de votre application nécessite moins d'efforts qu'un démarrage à froid. Lors d'un démarrage à chaud, le système met votre activité au premier plan. Si toutes les activités de votre application sont toujours en mémoire, l'application n'a pas besoin de répéter l'initialisation des objets, le gonflage de la mise en page et l'affichage.

Toutefois, si une partie de la mémoire est définitivement vidée à la suite d'événements de nettoyage, tels que onTrimMemory(), ces objets doivent être recréés en réponse au démarrage à chaud.

Le démarrage à chaud présente le même comportement à l'écran que le démarrage à froid : Le processus système affiche un écran vide jusqu'à ce que l'application ait fini d'effectuer le rendu de l'activité.

Figure 2 : Schéma représentant les différents états de démarrage et leurs processus respectifs, chaque état commençant par le premier frame affiché.

Comment identifier le démarrage de l'application dans Perfetto

Pour déboguer les problèmes de démarrage de l'application, il est utile de déterminer exactement ce qui est inclus dans la phase de démarrage de l'application. Pour identifier toute la phase de démarrage de l'application dans Perfetto, procédez comme suit :

  1. Dans Perfetto, recherchez la ligne contenant la métrique dérivée des démarrages de l'application Android. Si vous ne la voyez pas, essayez de capturer une trace à l'aide de l'application de traçage système sur l'appareil.

    Figure 3 : Le segment des métriques dérivées des démarrages de l'application Android dans Perfetto.
  2. Cliquez sur le segment associé, puis appuyez sur m pour le sélectionner. Des crochets apparaissent autour du segment et indiquent la durée du processus. La durée est également affichée dans l'onglet Current selection (Sélection actuelle).

  3. Épinglez la ligne des démarrages de l'application Android en cliquant sur l'icône en forme de punaise, qui s'affiche lorsque vous maintenez le pointeur sur la ligne.

  4. Faites défiler l'écran jusqu'à la ligne contenant l'application en question, puis cliquez sur la première cellule pour développer la ligne.

  5. Effectuez un zoom avant sur le thread principal, généralement en haut, en appuyant sur w (appuyez respectivement sur s, a ou d pour effectuer un zoom arrière, vous déplacer vers la gauche ou vous déplacer vers la droite).

    Figure 4 : Segment des métriques dérivées des démarrages de l'application Android à proximité du thread principal de l'application.
  6. Le segment de métriques dérivées permet de voir plus facilement ce qui est inclus dans le démarrage de l'application, ce qui vous permet de poursuivre le débogage plus en détail.

Utiliser les métriques pour inspecter et améliorer les démarrages

Pour diagnostiquer correctement les performances liées au délai de démarrage, vous pouvez suivre les métriques qui indiquent le temps nécessaire au démarrage de votre application. Android vous propose plusieurs façons de vous signaler que votre application rencontre un problème et vous aide à le diagnostiquer. Android Vitals peut vous avertir que le problème se produit, et les outils de diagnostic peuvent vous aider à le diagnostiquer.

Avantages des métriques de démarrage

Android utilise les métriques Délai d'affichage initial (TTID) et Délai d'affichage total (TTFD) pour optimiser les démarrages d'application à froid et tiède. Android Runtime (ART) utilise les données de ces métriques pour précompiler efficacement le code afin d'optimiser les démarrages ultérieurs.

Des démarrages plus rapides entraînent une interaction plus durable des utilisateurs avec votre application, ce qui réduit le nombre d'instances de sortie anticipée, de redémarrage ou de navigation vers une autre application.

Android Vitals

Android Vitals peut vous aider à améliorer les performances de votre application en vous alertant via la Play Console lorsque les temps de démarrage de votre application sont trop longs.

Android Vitals considère que le délai de démarrage suivant de votre application est excessif :

  • le démarrage à froid prend cinq secondes ou plus ;
  • le démarrage tiède prend deux secondes ou plus ;
  • le démarrage à chaud prend 1,5 seconde ou plus.

Android Vitals utilise la métrique Délai d'affichage initial. Pour savoir comment Google Play collecte les données Android Vitals, consultez la documentation de la Play Console.

Délai d'affichage initial

Le délai d'affichage initial (TTID) correspond au temps nécessaire pour afficher le premier frame de l'interface utilisateur de l'application. Cette métrique mesure le temps nécessaire pour qu'une application produise sa première image, y compris l'initialisation du processus à froid, la création d'activités lors d'un démarrage à froid ou tiède, et l'affichage de la première image. Un TTID faible permet d'améliorer l'expérience utilisateur en permettant aux utilisateurs de voir rapidement le lancement de votre application. Le TTID est signalé automatiquement pour chaque application par le framework Android. Lorsque vous optimisez le démarrage d'une application, nous vous recommandons d'implémenter reportFullyDrawn pour obtenir des informations jusqu'au TTFD.

Le TTID est mesuré en tant que valeur temporelle représentant le temps écoulé total, qui comprend la séquence d'événements suivante :

  • Lancer le processus
  • Initialiser les objets
  • Créer et initialiser l'activité
  • Gonfler la mise en page
  • Afficher l'application pour la première fois

Récupérer le TTID

Pour trouver le TTID, recherchez dans l'outil de ligne de commande Logcat une ligne de sortie contenant une valeur appelée Displayed. Cette valeur est le TTID et ressemble à l'exemple suivant, dans lequel le TTID est de 3 s 534 ms :

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms

Pour trouver le TTID dans Android Studio, désactivez les filtres dans la vue Logcat à partir du menu déroulant des filtres, puis recherchez le code temporel Displayed, comme illustré dans la figure 5. Cette opération est nécessaire, car c'est le serveur système, et non l'appli elle-même, qui gère ce journal.

Figure 5 : Filtres désactivés et valeur Displayed dans Logcat.

La métrique Displayed dans la sortie Logcat ne capture pas systématiquement le temps nécessaire avant que toutes les ressources ne soient chargées et affichées. Elle exclut les ressources qui ne sont pas référencées dans le fichier de mise en page ou que l'application crée dans le cadre de l'initialisation de l'objet. Elle exclut ces ressources, car leur chargement est un processus intégré et ne bloque pas l'affichage initial de l'application.

La ligne Displayed de la sortie Logcat contient parfois un champ supplémentaire indiquant la durée totale. Par exemple :

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms (total +1m22s643ms)

Dans ce cas, la première mesure ne concerne que l'activité qui a été visualisée pour la première fois. La mesure de la durée total commence au début du processus de l'application et peut inclure une autre activité démarrée en premier, mais qui n'affiche rien à l'écran. La mesure du temps total n'est affichée que s'il existe une différence entre l'activité unique et le temps total de démarrage.

Nous vous recommandons d'utiliser Logcat dans Android Studio. Toutefois, si vous n'utilisez pas Android Studio, vous pouvez également mesurer le TTID en exécutant votre application avec la commande adb du gestionnaire d'activités du shell. Exemple :

adb [-d|-e|-s <serialNumber>] shell am start -S -W
com.example.app/.MainActivity
-c android.intent.category.LAUNCHER
-a android.intent.action.MAIN

La métrique Displayed apparaît dans la sortie Logcat comme précédemment. La fenêtre de terminal affiche les éléments suivants :

Starting: Intent
Activity: com.example.app/.MainActivity
ThisTime: 2044
TotalTime: 2044
WaitTime: 2054
Complete

Les arguments -c et -a sont facultatifs et vous permettent de spécifier une <category> et une <action>.

Délai d'affichage total

Le délai d'affichage total (TTFD) correspond au temps nécessaire pour qu'une application devienne interactive pour l'utilisateur. Il est indiqué comme le temps nécessaire pour afficher le premier frame de l'interface utilisateur de l'application, ainsi que le contenu qui se charge de manière asynchrone après l'affichage du frame initial. Il s'agit généralement du contenu principal chargé à partir du réseau ou du disque, comme indiqué par l'application. En d'autres termes, le TTFD inclut le TTID, ainsi que le temps nécessaire pour que l'appli soit utilisable. Un faible niveau du TTFD améliore l'expérience utilisateur en leur permettant d'interagir rapidement avec votre application.

Le système détermine le TTID lorsque Choreographer appelle la méthode onDraw() de l'activité et lorsqu'il sait qu'il l'appelle pour la première fois. Toutefois, le système ne sait pas quand déterminer le TTFD, car chaque application se comporte différemment. Pour déterminer le TTFD, l'appli doit signaler au système lorsqu'elle atteint l'état d'affichage complet.

Récupérer le TTFD

Pour trouver le TTFD, signalez l'état d'affichage complet en appelant la méthode reportFullyDrawn() du ComponentActivity. La méthode reportFullyDrawn indique lorsque l'application est complètement affichée et dans un état utilisable. Le TTFD correspond au temps écoulé entre le moment où le système reçoit l'intent de lancement de l'application et le moment où reportFullyDrawn() est appelé. Si vous n'appelez pas reportFullyDrawn(), aucune valeur TTFD n'est signalée.

Pour mesurer le TTFD, appelez reportFullyDrawn() une fois que l'interface utilisateur et toutes les données sont complètement affichées. N'appelez pas reportFullyDrawn() avant que la fenêtre de la première activité ne soit apparue et affichée comme mesurée par le système, car celui-ci indique alors la durée mesurée par le système. En d'autres termes, si vous appelez reportFullyDrawn() avant que le système ne détecte le TTID, il signale à la fois le TTID et le TTFD comme la même valeur, et cette valeur correspond alors à celle du TTID.

Lorsque vous utilisez reportFullyDrawn(), Logcat affiche une sortie semblable à l'exemple suivant, dans lequel le TTFD est de 1 s 54 ms :

system_process I/ActivityManager: Fully drawn {package}/.MainActivity: +1s54ms

La sortie Logcat inclut parfois une durée total, comme indiqué dans la section Délai d'affichage initial.

Si les délais d'affichage sont plus lents que vous le souhaitez, vous pouvez essayer d'identifier les goulots d'étranglement dans le processus de démarrage.

Vous pouvez utiliser reportFullyDrawn() pour signaler l'état d'affichage complet dans les cas de base où vous savez que l'état d'affichage complet est atteint. Toutefois, dans les cas où les threads en arrière-plan doivent terminer le travail en arrière-plan avant que l'état d'affichage complet ne soit atteint, vous devez retarder reportFullyDrawn() pour une mesure du TTFD plus précise. Pour savoir comment retarder reportFullyDrawn(), consultez la section suivante.

Améliorer la précision du temps de démarrage

Si votre application effectue un chargement différé et que l'affichage initial n'inclut pas toutes les ressources, par exemple lorsque votre application récupère des images du réseau, vous pouvez retarder l'appel de reportFullyDrawn jusqu'à ce que votre application devienne utilisable. Vous pouvez ainsi inclure le remplissage de la liste dans votre analyse comparative.

Par exemple, si l'interface utilisateur contient une liste dynamique telle qu'une RecyclerView ou une liste différée, elle peut être renseignée par une tâche en arrière-plan qui se terminera après le premier affichage de la liste et, par conséquent, une fois que l'interface utilisateur sera marquée comme entièrement dessinée. Dans ce cas, le remplissage de la liste n'est pas inclus dans l'analyse comparative.

Pour inclure le remplissage de la liste dans votre analyse comparative, obtenez FullyDrawnReporter à l'aide de getFullyDrawnReporter(), et ajoutez-y un "rapporteur" dans le code de votre application. Libérez ce rapporteur lorsque la tâche en arrière-plan aura rempli la liste.

FullyDrawnReporter n'appelle pas la méthode reportFullyDrawn() tant que tous les rapporteurs ajoutés ne sont pas libérés. En ajoutant un rapporteur jusqu'à la fin du processus en arrière-plan, le délai inclut également le temps nécessaire pour remplir la liste dans les données de temps de démarrage. Cela ne modifie pas le comportement de l'application aux yeux de l'utilisateur, mais permet aux données de temps de démarrage d'inclure le temps nécessaire pour renseigner la liste. reportFullyDrawn() n'est appelé que lorsque toutes les tâches sont terminées, quel que soit l'ordre.

L'exemple suivant montre comment exécuter plusieurs tâches en arrière-plan simultanément, chacune enregistrant son propre rapport :

Kotlin

class MainActivity : ComponentActivity() {

    sealed interface ActivityState {
        data object LOADING : ActivityState
        data object LOADED : ActivityState
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            var activityState by remember {
                mutableStateOf(ActivityState.LOADING as ActivityState)
            }
            fullyDrawnReporter.addOnReportDrawnListener {
                activityState = ActivityState.LOADED
            }
            ReportFullyDrawnTheme {
                when(activityState) {
                    is ActivityState.LOADING -> {
                        // Display the loading UI.
                    }
                    is ActivityState.LOADED -> {
                        // Display the full UI.
                    }
                }
            }
            SideEffect {
                lifecycleScope.launch(Dispatchers.IO) {
                    fullyDrawnReporter.addReporter()

                    // Perform the background operation.

                    fullyDrawnReporter.removeReporter()
                }
                lifecycleScope.launch(Dispatchers.IO) {
                    fullyDrawnReporter.addReporter()

                    // Perform the background operation.

                    fullyDrawnReporter.removeReporter()
                }
            }
        }
    }
}

Java

public class MainActivity extends ComponentActivity {
    private FullyDrawnReporter fullyDrawnReporter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        fullyDrawnReporter = getFullyDrawnReporter();
        fullyDrawnReporter.addOnReportDrawnListener(() -> {
            // Trigger the UI update.
            return Unit.INSTANCE;
        });

        new Thread(new Runnable() {
            @Override
            public void run() {
                fullyDrawnReporter.addReporter();

                // Do the background work.

               fullyDrawnReporter.removeReporter();
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                fullyDrawnReporter.addReporter();

                // Do the background work.

                fullyDrawnReporter.removeReporter();
            }
        }).start();
    }
}

Si votre application utilise Jetpack Compose, vous pouvez utiliser les API suivantes pour indiquer l'état entièrement dessiné :

  • ReportDrawn : indique que votre composable est immédiatement prêt à interagir.
  • ReportDrawnWhen : utilise un prédicat, comme list.count > 0, pour indiquer à quel moment votre composable sera prêt à interagir.
  • ReportDrawnAfter : utilise une méthode de suspension qui, lorsqu'elle se termine, indique que votre composable est prêt à interagir.
Identifier les goulots d'étranglement

Pour identifier les goulots d'étranglement, vous pouvez utiliser le Profileur de processeur Android Studio. Pour en savoir plus, consultez la section Inspecter l'activité du processeur avec le Profileur de processeur.

Vous pouvez également obtenir des renseignements sur les goulots d'étranglement potentiels grâce au traçage intégré dans les méthodes onCreate() de vos applications et activités. Pour en savoir plus sur le traçage intégré, consultez la documentation sur les fonctions Trace et la présentation du traçage système.

Résoudre les problèmes courants

Cette section traite de plusieurs problèmes qui affectent souvent les performances de démarrage des applications. Ces problèmes concernent principalement l'initialisation des objets d'application et d'activité, ainsi que le chargement des écrans.

Initialisation d'application à forte charge

Les performances de lancement peuvent être affectées lorsque votre code ignore l'objet Application et exécute un travail à forte charge ou une logique complexe lors de l'initialisation de cet objet. Votre application peut perdre du temps au démarrage si les sous-classes Application effectuent des initialisations qui ne sont pas nécessaires à ce stade.

Certaines initialisations peuvent être complètement inutiles, telles que l'initialisation des informations d'état pour l'activité principale lorsque l'application est démarrée en réponse à un intent. Avec un intent, l'application n'utilise qu'un sous-ensemble des données d'état précédemment initialisées.

Lors de l'initialisation de l'application, d'autres défis incluent les événements de récupération de mémoire à impact élevé ou en quantité importante, ou les opérations d'E/S sur le disque exécutées simultanément à l'initialisation, ce qui bloque encore davantage le processus d'initialisation. La récupération de mémoire est particulièrement importante pour l'environnement d'exécution Dalvik. L'environnement d'exécution Art exécute la récupération de mémoire en même temps, ce qui réduit l'impact de cette opération.

Diagnostiquer le problème

Vous pouvez utiliser le traçage de méthode ou le traçage intégré pour essayer de diagnostiquer le problème.

Traçage de méthode

L'exécution du Profileur de processeur révèle que la méthode callApplicationOnCreate() appelle votre méthode com.example.customApplication.onCreate. Si l'outil montre que l'exécution de ces méthodes prend beaucoup de temps, vous devez examiner les tâches à effectuer de plus près.

Traçage intégré

Utilisez le traçage intégré pour identifier les causes probables de ces problèmes, notamment :

  • La fonction onCreate() initiale de votre application
  • Tout objet Singleton global initialisé par votre application
  • Toute opération d'E/S sur le disque, désérialisation ou boucle serrée qui peut se produire durant le goulot d'étranglement

Les solutions au problème

Que le problème soit dû à des initialisations inutiles ou à des opérations d'E/S sur le disque, l'initialisation différée est la solution. En d'autres termes, n'initialisez que les objets qui sont nécessaires immédiatement. Au lieu de créer des objets statiques globaux, passez à un modèle Singleton où l'application initialise les objets uniquement la première fois qu'elle en a besoin.

Envisagez également d'utiliser un framework d'injection de dépendances comme Hilt, qui crée des objets et des dépendances lors de leur première injection.

Si votre application utilise des fournisseurs de contenu pour initialiser les composants de l'application au démarrage, envisagez plutôt d'utiliser la bibliothèque de démarrage d'application.

Initialisation d'activité à forte charge

La création d'activités implique souvent d'importants efforts. Il est souvent possible d'optimiser cette tâche afin d'améliorer les performances. Ces problèmes courants sont les suivants :

  • Gonflage des mises en page complexes ou de grande taille
  • Blocage de la visualisation à l'écran sur le disque ou l'E/S réseau
  • Chargement et décodage des bitmaps
  • Trame des objets VectorDrawable
  • Initialisation d'autres sous-systèmes de l'activité

Diagnostiquer le problème

Dans ce cas, le traçage de méthode et le traçage intégré peuvent également s'avérer utiles.

Traçage de méthode

Lorsque vous utilisez le Profileur de processeur, faites attention aux constructeurs de sous-classes Application et aux méthodes com.example.customApplication.onCreate() de votre application.

Si l'outil montre que l'exécution de ces méthodes prend beaucoup de temps, vous devez examiner les tâches à effectuer de plus près.

Traçage intégré

Utilisez le traçage intégré pour identifier les causes probables de ces problèmes, notamment :

  • La fonction onCreate() initiale de votre application
  • Tout objet Singleton global qu'elle initialise
  • Toute opération d'E/S sur le disque, désérialisation ou boucle serrée qui peut se produire durant le goulot d'étranglement

Les solutions au problème

Il existe de nombreux goulots d'étranglement potentiels, mais voici deux problèmes courants et leurs solutions :

  • Plus la hiérarchie des vues est grande, plus l'application met du temps à la gonfler. Pour résoudre ce problème, procédez comme suit :
    • Aplatissez la hiérarchie des vues en réduisant les mises en page redondantes ou imbriquées.
    • Ne gonflez pas les parties de l'interface utilisateur qui n'ont pas besoin d'être visibles lors du lancement. Utilisez plutôt un objet ViewStub comme espace réservé pour les sous-hiérarchies, que l'application pourra gonfler à un moment plus approprié.
  • Initialiser l'ensemble de vos ressources sur le thread principal peut également ralentir le démarrage. Pour résoudre ce problème :
    • Déplacez l'initialisation de toutes les ressources afin que l'application puisse l'effectuer de manière différée sur un thread différent.
    • Autorisez l'application à charger et afficher vos vues, puis mettez à jour les propriétés visuelles qui dépendent de bitmaps et d'autres ressources.

Écrans de démarrage personnalisés

Le démarrage peut prendre plus de temps si vous avez déjà utilisé l'une des méthodes suivantes pour implémenter un écran de démarrage personnalisé sous Android 11 (niveau d'API 30) ou version antérieure :

  • Utilisation de l'attribut de thème windowDisablePreview pour désactiver l'écran vierge initial affiché par le système lors du lancement
  • Utilisation d'une Activity dédiée

À partir d'Android 12, la migration vers l'API SplashScreen est requise. Cette API accélère le démarrage et vous permet d'ajuster votre écran de démarrage comme suit :

De plus, avec la bibliothèque de compatibilité, vous pouvez rétroporter l'API SplashScreen, ce qui permet d'activer la rétrocompatibilité et de créer une apparence cohérente pour les écrans de démarrage, quelle que soit la version d'Android.

Pour en savoir plus, consultez le guide de migration des écrans de démarrage.