web-dev-qa-db-fra.com

Comment réparer le rendu lent (signes vitaux Android)

J'ai une application répertoriée comme dans les 25% inférieurs dans la nouvelle console Google Play - Android section vitales pour le rendu lent. Je suis préoccupé par cela à cause de ces articles qui semble dire que Google Play peut pénaliser votre application dans le classement Play Store si vous tombez dans les 25% les plus bas.

Cependant, il semble impossible d'améliorer cette métrique pour mon application. Il joue de la musique et dispose d'une SeekBar et de TextView qui est mis à jour toutes les 250 ms comme n'importe quel lecteur de musique. J'ai fait le programme de base minimum pour démontrer:

public class MainActivity extends AppCompatActivity {

    int count;
    SeekBar seekBar;
    TextView textView;

    Runnable runnable =
            new Runnable() {
                @Override
                public void run() {
                    textView.setText(Integer.toString(count));
                    seekBar.setProgress(count);
                    ++count;
                    seekBar.postDelayed(runnable, 250);
                }
            };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        seekBar = (SeekBar) findViewById(R.id.seek);
        textView = (TextView) findViewById(R.id.text);
        seekBar.post(runnable);
    }
}

Projet complet ici: https://github.com/svenoaks/SlowRendering.git

Lorsque j'exécute ce programme sur du matériel similaire aux appareils Nexus, j'obtiens ces résultats pour un
adb Shell dumpsys gfxinfo com.example.xyz.slowrendering commande:

Stats since: 19222191084749ns
Total frames rendered: 308
Janky frames: 290 (94.16%)
90th percentile: 32ms
95th percentile: 36ms
99th percentile: 44ms
Number Missed Vsync: 2
Number High input latency: 0
Number Slow UI thread: 139
Number Slow bitmap uploads: 0
Number Slow issue draw commands: 283

Cela signifierait que presque toutes mes images prennent> 16 ms pour être rendues, je suppose en raison de la nature périodique de la mise à jour. Toutes les autres applications de lecteur de musique que j'ai testées ont également ce problème de rendu lent pour autant que je puisse voir. Je crains que l'algorithme de Google ne ruine le classement de mon application, existe-t-il un moyen d'améliorer mon score?

16
Steve M

Le TextView dans votre disposition est à l'origine du problème. Parce qu'il a layout width De wrap_content, Ce qui dit que sa largeur doit être égale à la largeur du contenu (le texte dans cet exemple). Par conséquent, chaque fois que vous appelez TextView.setText, Une passe de mesure/disposition coûteuse doit se produire. Un simple réglage de layout_width Sur match_parent Résoudra le problème.

enter image description here

enter image description here

Voici deux images tirées de systrace, elles montrent le travail exécuté sur le thread d'interface utilisateur dans 1 cadre. Celui du haut se fait avec layout_width=wrap_content Et celui du bas est avec layout_width=match_parent.

Deux méthodes suivantes que j'ai testées amélioreront la fréquence d'images:

  • Si vous postez le runnable sur une durée plus courte comme 16 ms (seekBar.postDelayed(runnable, 16)), vous obtenez ce 60fps lisse: enter image description here

    P/s: Je ne sais pas encore pourquoi.

  • Utilisez une autre méthode pour mettre à jour la valeur count au lieu de l'intérieur de Runnable. Utilisez View.postOnAnimation(Runnable) pour replanifier le Runnable. Le résultat est 60FPS pour l'exemple de projet.

EDIT: deux Runnable qui utilisent postOnAnimation(Runnable)

Runnable runnable =
  new Runnable() {
    @Override
    public void run() {
      textView.setText(Integer.toString(count));
      seekBar.setProgress(count);
      seekBar.postOnAnimation(this);
    }
  };



Runnable updateCount = new Runnable() {
    @Override public void run() {
      ++count;
      seekBar.postDelayed(this, 250);
    }
  };
16
Tin Tran

J'ai vérifié ton code. Je ne sais pas si c'est le code réel ou si vous en avez plus. Dans tous les cas, j'attirerai l'attention sur certains des problèmes de rendu dans Android.

1. OverDraw

Overdraw est l'endroit où vous perdez du temps de traitement GPU en coloriant des pixels qui ne sont recolorés que par autre chose. Ceux-ci peuvent être courants si vous avez ajouté un arrière-plan à la disposition de votre conteneur parent, puis les enfants sont également ajoutés un arrière-plan ou si vous avez ajouté un arrière-plan commun dans votre fichier de styles pour le thème de l'application, puis ajouté des arrière-plans au reste du xml les fichiers de mise en page que vous avez créés.

Les causes du dépassement peuvent être diverses, essayez de vérifier votre code pour cela. Un outil de développeur est installé sur tous les appareils mobiles pour vérifier les options de développeur dans Overdraw. Ici est la documentation officielle pour overdraw.

2. Afficher la hiérarchie

Pour rendre chaque vue, Android passe par trois étapes:

1. mesure

2. mise en page

3. tirer

Le temps qu'il faut Android pour terminer ces étapes est proportionnel au nombre de vues dans votre hiérarchie. Je vois dans votre fichier de disposition que vous avez une disposition de contraintes qui comprend une disposition linéaire. Je ne sais pas voir l'utilisation de cette disposition. La disposition des contraintes a été introduite pour aider les développeurs à réduire la hiérarchie des vues. Réduire le nombre d'enfants qu'une disposition particulière peut avoir. Il existe également un outil pour vous aider avec cela. Ici est l'officiel Android guide. Essayez ces étapes pour résoudre les problèmes de rendu du GPU.

3
Bawender Yandra