Optimisation des performances Android - optimisation du démarrage

La vitesse de démarrage d’une application est la première expérience de l’utilisateur. Il existe une règle des huit secondes sur Internet. Si un utilisateur attend huit secondes avant l’ouverture de l’application, 70 % des utilisateurs cesseront d’attendre.

 1. Commencer le classement

Heure de démarrage officielle de l'application 

  • Démarrage à froid

         L'étalon de mesure qui prend le plus de temps

  • Démarrage à chaud

         le plus rapide. Dans les coulisses~Devant la scène

  • Démarrage à chaud

         Plus rapide. Il ne fera que répéter le cycle de vie de l'activité, mais pas la création du processus et la création et le cycle de vie de l'Application.

processus de démarrage à froid

  1. L'utilisateur clique 
  2. Déclencher l'opération IPC
  3. Création du processus Process.start
  4. ActivityThread est l'entrée de chaque processus distinct. Il y aura une méthode principale pour créer la boucle de message et le gestionnaire.
  5. bindApplication crée une application par réflexion et appelle le cycle de vie de l'application
  6. Cycle de vie de l'activité Cycle de vie 
  7. ViewRootImpl démarre le véritable dessin de l'interface

Avant le démarrage à froid (on ne peut intervenir sur ce processus)

  • Démarrer l'application 
  • Charger une fenêtre vide 
  • Créer un processus

Tâches ultérieures

  • Créer une application 
  • Démarrer le fil principal
  • CreateMainActivity 
  • Charger la disposition
  • écran de mise en page
  • Premier cadre dessiné

Optimiser
        le cycle de vie des applications et des activités

2. Comment mesurer le temps de démarrage

mode de commande adb

        adb shell suis start -W packagename/首屏Activity 

    Caractéristiques:

  • Facile à utiliser hors ligne mais ne peut pas être mis en ligne
  • Heure non stricte et précise

La méthode de marquage manuel
        enterre les points au début et enterre les points au début et à la fin. La différence entre les deux
     fonctionnalités :       

         Précis, peut être mis en ligne, utilisation recommandée

     Évitez les malentendus

  • Le point de départ de l'heure de démarrage se trouve dans le attachBaseContext de l'application 
  • La position finale de l'heure de début reprend le premier affichage du flux.
  • addOnDrawListener nécessite l'API 16

ThisTime Le temps nécessaire pour démarrer la dernière activité
TotalTime Le temps nécessaire pour démarrer toutes les activités
WaitTime Le temps total nécessaire pour démarrer l'activité AMS

3. Démarrez les outils utilisés pour l'optimisation

 traceview,systrace 

  • Les deux outils se complètent
  • Comprendre correctement les outils et choisir les outils appropriés pour différents scénarios

vue de trace

  • avantage
    •  Forme graphique, affichant le temps d'exécution du code, les informations sur la pile d'appels, etc.
    • Informations complètes, y compris toutes les informations sur le fil de discussion
  •  Usage

      Debug.startMethodTracing("file name"); la taille par défaut est 8M. Si vous souhaitez une taille plus grande, passez le paramètre bufferSize. 
      Debug.stopMethodTracing()
      générera un fichier à la fin de la carte sd : Android/data/packagename /des dossiers

Il y a un explorateur de fichiers de périphériques sur le côté droit d'Android Studio, qui peut facilement ouvrir les fichiers du système de téléphonie mobile.
Après avoir ajouté le code d'ouverture et de fermeture, exécutez-le, actualisez-le sous l'emplacement de stockage et définissez un nom de fichier. Le fichier .trace sera généré.

  • Comment analyser
    • Le coin supérieur gauche est la plage de temps spécifiée avec précision via le code. Il y a une heure dans le coin inférieur gauche, ce qui n'est pas particulièrement important.
    • L'angle inférieur gauche contient des informations sur les threads. Vous pouvez voir le nombre total de threads et ce que chaque thread a fait à un moment précis. 

Il y a quatre onglets à droite 

  • De haut en bas

total : durée totale

soi :

enfants:

Par exemple : la fonction A est appelée, le temps global est total, une ligne de code est appelée dans la fonction A, puis la fonction B est exécutée. Son selfTime est l'heure à laquelle une ligne de code est exécutée et childrenTime est l'heure à laquelle la fonction B est exécutée. La somme de selfTime et childrenTime doit être égale à totalTime

Liste d'appels de fonction, cliquez sur le saut correspondant vers souse pour accéder au code détaillé

ThreadTime deviendra certainement inférieur, le temps d'exécution du CPU.
Wall Clock Time Le code se produit sur ce thread, le temps d'exécution réel

  • Appeler le chat 

Chaque ligne indique la période de temps de l'appel de fonction et la méthode verticale est appelée.
La couleur de l'appel d'API système est orange,
l'appel de fonction de l'application est vert et
l'appel d'API tiers est bleu.

  • Graphique de flamme de discussion en flamme

Graphique d'appel inversé, qui collecte la même séquence d'appels

  • De bas en haut

Qui m'a appelé est le contraire de Top down

Résumé :
        La surcharge d'exécution est importante et le tout sera ralenti. Cet outil est trop puissant et capturera toutes les fonctions d'exécution de tous les threads et l'ordre peut biaiser la
        direction de l'optimisation. Les avantages de
        traceview et de traceview du profileur de processeur 
                peuvent être enfoui dans le code Utiliser l'analyse du profileur de processeur
                Il est presque impossible d'utiliser simplement le profileur de processeur pour capturer l'emplacement de démarrage précis.

 trace système

Combinez les données du noyau Android pour générer
un script Python de rapport HTML

  • Usage

• python systrace.py -t 10 [autres options] [catégories]

  • Documentation officielle :

https://developer.android.com/studio/command-line/systrace#command_options

  • Cas d'utilisation

python /Users/Liuzhao.Future/Library/Android/sdk/platform-tools/ systrace/systrace.py -b 32768 -t 5 -a com.optimize.performance -o performances. html sched gf vue wm am app

  • utilisé dans le code

Ouvert : TraceCompat.beginSection(« apponCreate »)
Fin : TraceCompat.endSection 

  • Analyser les fichiers HTML

Le nombre de cœurs de processeur dépend des différents téléphones mobiles. Certains fabricants de téléphones mobiles vous proposent 8 cœurs. Certains téléphones mobiles ont 8 cœurs, mais seuls 4 cœurs sont utilisés pour vous.

  • Résumer:
    • Léger, peu coûteux, faites ce que vous voulez
    • Reflète intuitivement l'utilisation du processeur

cpuTime et wallTime

  • wallTime est l'heure à laquelle le code est exécuté
  • cpuTime est le temps pendant lequel le code consomme le CPU (indicateur clé)

Exemple : Pourquoi les deux ont-ils
        des conflits de verrouillage différents ? Par exemple, un thread doit acquérir le verrou A pour l'exécution, mais le verrou A est détenu par d'autres threads et n'a pas été libéré. ​​Cependant, ce thread est léger et ne prend que peu de temps. temps du CPU. Donc à ce moment, cpuTime sera très court et wallTime sera très long.

4. Comment obtenir élégamment la consommation de temps CPU

Besoin de savoir quelle méthode prend le plus de temps

  • Méthode conventionnelle : points d’enfouissement manuels
    • Très envahissant
    • Lourde charge de travail
  • Méthode AOP : Aspect Oriented Programming, programmation orientée aspect
    • Traitement unifié du même type de problèmes
    • Ajoutez du code sans intrusion

Utilisation des aspects

  • chemin de classe 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.0'
  • implémentation 'org.aspectjaspectjrt:1.8.+'
  • appliquer le plugin : 'android-aspectix'

introduire

  • Rejoindre des points
    • Le point d'exécution lorsque le programme est en cours d'exécution peut être utilisé comme emplacement pour les aspects
    • appel de fonction, exécution
    • Obtenir et définir des variables
    • Initialisation de la classe
  • PointCut
    • JoinPoints avec conditions
  • Conseil
    • Une sorte de Hook, où le code doit être inséré
    • Avant : exécuté avant PointCut
    • Après : exécuté après PointCut
    • Autour : exécuter séparément avant et après Pointcut
  • Introduction à la grammaire
    //Before:Advice,具体插入位置
    //execution :处理Join Point的类型
    //(* android.app.Activity.on**(.)):匹配规则
    @Before("execution(* android.app.Activity.on** (.))") 
    public void onActivityCalled (JoinPoint joinPoint) thr
    ows Throwable {
        ……
    }
  • Cas d'utilisation
@Aspect
public class Performanceaop{

    Around("call(*com.optimize.performance.PerformanceApp.**(..))") 
    public void getTime(ProceedingJoinPointjoinPoint){
        Signature signature=joinPoint.getSignature(); 
        String name=signaturetoShortString(); 
        long time=System.currentTimeMillis(); 
        try {
            joinPoint.proceed();
        } catch(Throwable throwable){
            throwable.printStackTrace();
        }
        LogUtils.i(msg:name+" cost "+(System.currentTimeMillis() - time));
    }
}
  • avantage
    • Non invasif
    • Facile à modifier

5. Optimisation asynchrone

  • Optimisation asynchrone générale : utilisation de pools de threads pour l'optimisation asynchrone
  • Launcher (la solution optimale pour l'optimisation des startups asynchrones)

Mode asynchrone régulier

Points à noter concernant les méthodes asynchrones conventionnelles :

  • Tout le code ne peut pas être directement asynchrone
  1. Ne répond pas aux exigences asynchrones : certaines tâches doivent être exécutées dans le thread principal
  2. Elle doit être complétée à un certain stade. Des tâches asynchrones sont utilisées dans l'interface splash. Lors de l'exécution de l'interface, certains codes doivent être complétés à un certain stade avant que la tâche asynchrone ne soit terminée. La solution : CountDownLatch équivaut à l'ajout d'un verrou. .
  3. Distinguer les tâches gourmandes en CPU et en E/S

Points faibles des solutions asynchrones conventionnelles :

  • Le code n'est pas assez élégant
  • La scène est difficile à gérer (dépendance), terminer une tâche dans un délai précis
  • Coûts d'entretien élevés

Mode lanceur

Idée de base :
     exploiter pleinement les multicœurs du processeur et trier automatiquement la séquence de tâches.
Processus de lancement :

  • Le code est orienté tâche et la logique de démarrage est résumée dans la tâche 
  • Générer un graphe acyclique dirigé basé sur les dépendances de toutes les tâches
  • Les multithreads sont exécutés séquentiellement en fonction de la priorité triée.

6. Initialisation retardée

  • Solution générale : handler.postDelay 
  • Meilleure solution : initialiser les tâches retardées par lots

Problèmes avec les solutions conventionnelles :

  • Le timing est difficile à contrôler
  • Provoquant un décalage d'alimentation

Avantages de la meilleure solution : Tirant parti de la fonctionnalité IdleHandler, exécution inactive

  • Le temps d’exécution est clair
  • Réduire le décalage d'alimentation

7. Synthèse : lancer la politique générale d'optimisation

  • Chargement asynchrone, retardé et paresseux
  • Combiner technologie et business

8. Précautions

  • Autorisations de modification du code de démarrage de Convergence
  • La modification du code de démarrage en conjonction avec Ci nécessite un examen ou une notification

9. Autres options

  • Charger SharedPreferences à l’avance 

        Chargez avant multidex, utilisez pleinement cette étape et le CPU 
        écrase getApplicationContext et renvoie ceci

  • Ne démarrez pas les processus enfants au démarrage

        Les processus enfants partageront les ressources du processeur, ce qui entraînera une surcharge du processeur du processus principal.
         Faites attention à la séquence de démarrage. App onCreate est précédé de ContentProvider. 

  • Optimisation du chargement des classes, chargement des classes asynchrones à l'avance
  • Supprimer GC pendant la phase de démarrage 
  • Verrouillage de la fréquence du processeur

Je suppose que tu aimes

Origine blog.csdn.net/weixin_42277946/article/details/131808262
conseillé
Classement