Je suis en retard pour la fête, mais j'espère que cela sera un complément utile aux autres réponses données ici...
Répondre à la question / tl:dr ;
J'ai besoin de savoir comment je peux déterminer le "trop de travail" que mon application peut faire puisque tout mon traitement est effectué dans AsyncTasks.
Les personnes suivantes sont toutes candidates :
- IO ou des traitements coûteux sur le thread principal (chargement des éléments graphiques, gonflement des mises en page et réglage des paramètres).
Uri
sur ImageView
Tout est constitué d'entrées-sorties sur le fil principal.)
- Rendu large/complexe/profond
View
hiérarchies
- L'invalidation de grandes parties d'un
View
hiérarchie
- Coûteux
onDraw
dans les méthodes personnalisées View
's
- Calculs coûteux dans les animations
- Exécution de threads "travailleurs" à une priorité trop élevée pour être considérée comme "d'arrière-plan" (
AsyncTask
sont "en arrière-plan" par défaut, java.lang.Thread
est no )
- Générer beaucoup de déchets, ce qui amène le ramasseur de déchets à "arrêter le monde" - y compris le fil principal - pendant qu'il nettoie.
En fait, pour déterminer la cause spécifique dont vous aurez besoin pour profiler votre application.
Plus de détails
J'ai essayé de comprendre le Chorégraphe en expérimentant et en regardant le code .
La documentation de Choreographer s'ouvre sur "Coordonne le timing des animations, de la saisie et du dessin", ce qui est une bonne description, mais le reste met trop l'accent sur les animations.
Le Chorégraphe est en fait responsable de l'exécution de 3 types de callbacks, qui se déroulent dans cet ordre :
- les rappels de traitement des entrées (traitement des entrées de l'utilisateur telles que les événements tactiles)
- les callbacks d'animation pour le tweening entre les images, fournissant un temps de départ d'image stable à toutes les animations en cours. L'exécution de ces callbacks en second signifie que tous les calculs liés à l'animation (par exemple, le changement de position des vues) ont déjà été effectués au moment où le troisième type de callback est invoqué...
- les callbacks de traversée de vue pour dessiner la hiérarchie de la vue.
L'objectif est de faire correspondre le taux auquel les vues invalidées sont redessinées (et les animations interpolées) avec la vsync de l'écran - généralement 60fps.
L'avertissement concernant les images sautées semble être une réflexion après coup : Le message est enregistré si un simple passer par les 3 étapes prend plus de 30x la durée prévue de la trame, de sorte que le plus petit nombre que vous pouvez vous attendre à voir dans les messages de log est "sauté". 30 cadres" ; Si chaque prend 50% plus de temps qu'il ne devrait, vous sauterez quand même 30 images ( vilain ! ) mais vous ne serez pas prévenu.
D'après les trois étapes concernées, il est clair que les animations ne sont pas les seules à pouvoir déclencher l'avertissement : L'invalidation d'une partie significative d'une grande View
ou une View
avec une méthode onDraw compliquée pourrait suffire.
Par exemple, ceci déclenchera l'avertissement de manière répétée :
public class AnnoyTheChoreographerActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_linear_layout);
ViewGroup root = (ViewGroup) findViewById(R.id.root);
root.addView(new TextView(this){
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
long sleep = (long)(Math.random() * 1000L);
setText("" + sleep);
try {
Thread.sleep(sleep);
} catch (Exception exc) {}
}
});
}
}
... ce qui produit un enregistrement comme celui-ci :
11-06 09:35:15.865 13721-13721/example I/Choreographer﹕ Skipped 42 frames! The application may be doing too much work on its main thread.
11-06 09:35:17.395 13721-13721/example I/Choreographer﹕ Skipped 59 frames! The application may be doing too much work on its main thread.
11-06 09:35:18.030 13721-13721/example I/Choreographer﹕ Skipped 37 frames! The application may be doing too much work on its main thread.
Vous pouvez voir sur la pile pendant onDraw
que le chorégraphe est impliqué, que vous animiez ou non :
at exemple.AnnoyTheChoreographerActivity$1.onDraw(AnnoyTheChoreographerActivity.java:25) at Android.view.View.draw(View.java:13759)
... pas mal de répétitions...
at Android.view.ViewGroup.drawChild(ViewGroup.java:3169) at Android.view.ViewGroup.dispatchDraw(ViewGroup.java:3039) at Android.view.View.draw(View.java:13762) at Android.widget.FrameLayout.draw(FrameLayout.java:467) at com.Android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2396) at Android.view.View.getDisplayList(View.java:12710) at Android.view.View.getDisplayList(View.java:12754) at Android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1144) at Android.view.ViewRootImpl.draw(ViewRootImpl.java:2273) at Android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2145) at Android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1956) at Android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1112) at Android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4472) at Android.view.Choreographer$CallbackRecord.run(Choreographer.java:725) at Android.view.Choreographer.doCallbacks(Choreographer.java:555) at Android.view.Choreographer.doFrame(Choreographer.java:525) at Android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711) at Android.os.Handler.handleCallback(Handler.java:615) at Android.os.Handler.dispatchMessage(Handler.java:92) at Android.os.Looper.loop(Looper.java:137) at Android.app.ActivityThread.main(ActivityThread.java:4898)
Enfin, en cas de conflit avec d'autres threads qui réduisent la quantité de travail que le thread principal peut effectuer, le risque de sauter des images augmente considérablement, même si vous n'effectuez pas réellement le travail sur le thread principal.
Dans cette situation, il pourrait être considéré comme trompeur de suggérer que l'application en fait trop sur le thread principal, mais Android souhaite vraiment que les threads de travail soient exécutés en basse priorité. afin de les empêcher d'affamer le fil principal. Si vos threads de travail sont peu prioritaires, la seule façon de déclencher l'avertissement du Chorégraphe est d'en faire trop sur le thread principal.
0 votes
À partir de votre lien : Coordonne le timing des animations, des entrées et des dessins. On dirait qu'il est utilisé pour faire des animations dans l'interface utilisateur.
0 votes
Exécutez-vous dans l'émulateur ?
0 votes
Oui, je le suis. Je comprends que le Chorégraphe est probablement le composant qui gère les animations et que lorsqu'il n'a pas assez de cycles de processeur, il saute des images et affiche ce message de débogage. Ce qui me préoccupe, c'est de savoir ce qui, dans mon thread principal, pourrait être à l'origine de ce problème et comment le repérer. Pour l'instant, tous mes traitements sont effectués dans des threads d'arrière-plan.
7 votes
J'ai un code qui s'exécute dans un fil d'exécution qui effectue des calculs lourds et qui envoie périodiquement des mises à jour au fil d'exécution de l'interface utilisateur. Bien que cela ne bloque pas le thread de l'interface utilisateur, les entrées de l'utilisateur sont mises en file d'attente et ne s'affichent pas à l'écran avant la fin de l'incrément actuel du calcul du travailleur. Pendant que cela se produit, je reçois constamment des messages de Choreographer comme "Saut de 37 images", etc. Il y a eu une tentative de rendre Jelly Bean "doux comme du beurre" et je soupçonne que ces messages font partie de l'encouragement à ne pas avoir de saccades dans nos écrans.
0 votes
En fait, je ne me soucie pas de savoir si "x" images sont sautées. Je ne veux simplement pas que ces messages apparaissent dans mon logcat...cela m'irrite beaucoup !!!
1 votes
@Elenasys Vous avez marqué cette question comme étant un doublon d'une question qui a été posée bien plus tard, le 3 février '13. Cela ne me semble pas juste :)
0 votes
La question dont il est question ici a été posée plus tard, a reçu moins de votes, n'a pas de réponse acceptée et sa réponse la plus populaire est une simple copie de la documentation Android. Est-il possible pour quelqu'un avec une réputation suffisante d'inverser le drapeau de duplication ?