web-dev-qa-db-fra.com

L'application fait peut-être trop de travail sur son thread principal

Je suis nouveau dans l'environnement SDK/API Android. C'est la première fois que j'essaie de dessiner un graphique. J'ai essayé d'exécuter différents types de codes exemples dans l'émulateur à l'aide de 3 bibliothèques gratuites différentes, rien ne s'affiche dans l'écran de présentation. Le logcat répète le message suivant:

 W/Trace (1378): valeur inattendue de nativeGetEnabledTags: 0 
 I/Chorégraphe (1378): 55 images ignorées! L'application effectue peut-être trop de travail sur son thread principal. 

Le problème ne persistait pas et le graphique fonctionnait lorsque j'ai exécuté un exemple de code relatif à une copie d'évaluation d'une bibliothèque sous licence. 

302
user2038135

extrait de: Interface utilisateur Android: Correction des images sautées

Toute personne qui commence à développer une application Android voit ce message sur logcat “Choreographer (abc): xx frames sautées! L'application peut être faire trop de travail sur son fil principal. ” Alors, qu'est-ce que cela fait réellement signifie, pourquoi devriez-vous être concerné et comment le résoudre.

Cela signifie que votre code prend beaucoup de temps à traiter et à générer des cadres sont omis à cause de cela, peut-être à cause de certains lourds traitement que vous effectuez au cœur de votre application ou de votre base de données accès ou toute autre chose qui cause l’arrêt du fil pendant un moment . Voici une explication plus détaillée:

Chorégraphe permet aux applications de se connecter au vsync et à chronométrer correctement les choses pour améliorer les performances.

Les animations de vue Android utilisent en interne Choreographer pour la même chose but: bien chronométrer les animations et éventuellement améliorer performance.

Puisque Chorégraphe est informé de tous les événements vsync, je peux dire si l'un des Runnables transmis par Choreographer.post * apis ne se termine pas dans le temps d’une image, ce qui entraîne l’omission des images.

Selon ma compréhension, Choreographer ne peut détecter que le saut de cadre . Il n'y a aucun moyen de dire pourquoi cela se produit.

Le message “L’application fait peut-être trop de travail sur sa principale fil. "pourrait être trompeur.

la source : Signification des messages de Choreographer dans Logcat

Pourquoi vous devriez être inquiet

Lorsque ce message apparaît sur Android L'émulateur et le nombre d'images ignorées sont assez faibles (<100), puis vous pouvez parier que l'émulateur est lent - ce qui se produit presque tout le temps. Mais si le nombre d'images ignorées et grande et dans l’ordre de 300+, il peut y avoir de sérieux problèmes avec votre code. Les appareils Android ont une vaste gamme de matériel contrairement à iOS et appareils Windows. La RAM et la CPU varient et si vous voulez un des performances et une expérience utilisateur raisonnables sur tous les appareils, puis vous besoin de réparer cette chose. Lorsque les images sont ignorées, l'interface utilisateur est lente et laggy, ce qui n’est pas une expérience utilisateur souhaitable.

Comment le réparer

Pour résoudre ce problème, vous devez identifier les nœuds où il y a ou peut éventuellement arriver longue durée de traitement. Le meilleur moyen est de faire tous les traitements, peu importe leur taille, dans un fil séparé du fil principal de l'interface utilisateur. Ainsi soit-il en accédant aux données sous la forme SQLite Database ou faire des calculs difficiles ou simplement trier un tableau - Faites-le dans un fil différent

Maintenant, il y a un piège ici, vous allez créer un nouveau thread pour le faire ces opérations et lorsque vous exécutez votre application, celle-ci se bloque en disant «Seul le fil d’origine qui a créé une hiérarchie de vues peut toucher ses vues “. Vous devez savoir que l’UI sous Android peut être modifié par le fil principal ou le fil de l'interface utilisateur uniquement. Tout autre fil qui tente de le faire, échoue et se bloque avec cette erreur. Qu'est-ce que tu Il est nécessaire de créer un nouveau Runnable dans runOnUiThread et dans ce runnable vous devriez faire toutes les opérations impliquant l'interface utilisateur. Trouver un exemple ici .

Nous avons donc Thread et Runnable pour le traitement des données hors du thread principal, quoi d'autre? Il y a AsyncTask dans Android qui permet de faire longtemps processus sur le fil de l'interface utilisateur. C'est le plus utile quand vous les applications sont pilotées par les données ou par les API Web ou utilisent des interfaces utilisateur complexes comme ceux construits en utilisant Canvas. Le pouvoir d'AsyncTask est que c'est permet de faire les choses en arrière-plan et une fois que vous avez terminé, le traitement, vous pouvez simplement faire les actions requises sur l'interface utilisateur sans provoquant un effet de retard. Cela est possible parce que AsyncTask dérive du fil d’interface utilisateur d’Activity - toutes les opérations que vous effectuez sur l'interface utilisateur via AsyncTask sont effectués est un thread différent de l'interface utilisateur principale thread, Aucun obstacle à l'interaction de l'utilisateur.

Voilà donc ce que vous devez savoir pour rendre Android lisse applications et autant que je sache, chaque débutant reçoit ce message sur son console.

419
Elenasys

Comme d'autres ont répondu ci-dessus, "Sauté 55 images!" signifie qu'un traitement lourd est dans votre application. 

Pour mon cas, il n'y a pas de processus lourd dans ma candidature. Je double et triple tout vérifié et enlevé ces processus que je pense était un peu lourd. 

J'ai enlevé des fragments, des activités, des bibliothèques jusqu'à ce qu'il ne reste que le squelette. Mais le problème ne s'est pas résolu. J'ai décidé de vérifier les ressources et j'ai trouvé que certaines icônes et arrière-plans que j'utilise sont assez volumineux car j'ai oublié de vérifier la taille de ces ressources. 

Donc, ma suggestion est la suivante: si aucune des réponses ci-dessus ne vous aide, vous pouvez également vérifier la taille de vos fichiers de ressources.

196
Sithu

Moi aussi j'ai eu le même problème.
La mienne était un cas où j’utilisais une image d’arrière-plan en caractères dessinables. Cette image particulière mesurait environ 130 Ko et était utilisée pendant l’écran de démarrage et la page d’accueil de mon application Android.

Solution - Je viens de déplacer cette image dans le dossier drawables-xxx de drawables et je pouvais libérer une grande quantité de mémoire occupée à l'arrière-plan et les images sautées ne sautaient plus.

Update Utilisez le dossier de ressources 'nodp' pouvant être dessiné pour stocker les fichiers Pouvant être dessinés en arrière-plan .
Est-ce qu'un dossier pouvant être dessiné qualifié pour la densité ou drawable-nodpi a priorité?

55
Prakhar1001

Une autre cause fréquente de retards sur le thread d'interface utilisateur est l'accès SharedPreferences. Lorsque vous appelez un PreferenceManager.getSharedPreferences et d'autres méthodes similaires pour la première fois, le fichier .xml associé est immédiatement chargé et analysé dans le même fil de discussion .

Un des moyens efficaces de résoudre ce problème consiste à déclencher la première charge SharedPreference à partir du thread en arrière-plan, démarrée le plus tôt possible (par exemple, à partir de onCreate de votre classe Application). De cette façon, l'objet de préférence peut déjà être construit au moment où vous souhaitez l'utiliser.

Malheureusement, il est parfois nécessaire de lire un fichier de préférences au cours des premières phases de démarrage (par exemple, dans l'activité initiale ou même dans l'application elle-même). Dans de tels cas, il est toujours possible d'éviter de bloquer l'interface utilisateur en utilisant MessageQueue.IdleHandler. Faites tout ce que vous avez à faire sur le thread principal, puis installez IdleHandler pour exécuter du code une fois que votre activité a été entièrement dessinée. Dans ce Runnable, vous devriez pouvoir accéder à SharedPreferences sans retarder un trop grand nombre d’opérations de dessin et rendre malheureux Choreographer.

17
user1643723

Essayez d’utiliser les stratégies suivantes pour améliorer les performances de votre application:

  • Utilisez la programmation multi-threading si possible. Les avantages en termes de performances sont énormes, même si votre téléphone intelligent possède un cœur (les threads peuvent s'exécuter dans différents cœurs, si le processeur en a deux ou plus). Il est utile de séparer la logique de votre application de l'interface utilisateur. Utilisez les threads Java, AsyncTask ou IntentService. Vérifie ça .
  • Lisez et suivez les conseils de performance divers du site Web de développement Android. Vérifier ici .
15
MigDus

Je ne suis pas un expert, mais j'ai reçu ce message de débogage lorsque je voulais envoyer des données de mon application Android à un serveur Web. Bien que j'aie utilisé la classe AsyncTask et effectué le transfert de données en arrière-plan, pour récupérer les données de résultat du serveur, j'ai utilisé la méthode get () de la classe AsyncTask qui rend l'interface utilisateur synchrone, ce qui signifie que votre interface attendra trop longtemps. Mon conseil est donc de faire en sorte que votre application effectue chaque tâche liée au réseau sur un thread séparé. 

7
saba

J'ai eu le même problème. Android Emulator fonctionnait parfaitement sous Android <6.0. Lorsque j'ai utilisé l'émulateur Nexus 5 (Android 6.0), l'application fonctionnait très lentement avec I/Choreographer: Skipped frames dans les journaux.

Donc, j'ai résolu ce problème en modifiant l'option hardwareAccelerated du fichier manifeste en true comme ceci:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
    package="com.example.myapplication">

    <application Android:hardwareAccelerated="true">
        ...
    </application>
</manifest>
6
phen0menon

J'ai eu le même problème. Dans mon cas, j'avais 2 dispositions relatives imbriquées. RelativeLayout doit toujours effectuer deux passes de mesure. Si vous imbriquez RelativeLayouts, vous obtenez un algorithme de mesure exponentiel.

5
Radoslav

Optimisez vos images ... N'utilisez pas d'images de plus de 100 Ko ... Le chargement des images prend trop de temps processeur et votre application se bloque.

4
HarshitG

J'ai eu le même problème. Lorsque j'ai exécuté le code sur un autre ordinateur, cela a bien fonctionné. Sur le mien, cependant, il affichait "L’application fait peut-être trop de travail sur son fil principal". 

J'ai résolu mon problème en redémarrant le studio Android [Fichier -> Caches invalidés/Redémarrer -> cliquez sur "Invalider et redémarrer"].

1
sonida

Lisez d'abord l'avertissement. Cela dit plus de charge sur le fil principal. Vous devez donc simplement exécuter des fonctions avec davantage de travail dans un fil. 

0
Credoz

cela se produit généralement lorsque vous exécutez des processus longs dans le thread principal. vous pouvez ignorer des images inférieures à 200. Toutefois, si vous avez plus de 200 images ignorées, cela peut ralentir l'interface utilisateur de votre application. ce que vous pouvez faire est de faire ces processus dans un nouveau thread appelé thread de travail puis d'afficher le résultat avec la communication avec le thread principal. AsyncTask et RunOnUiThread dans la plupart des cas peuvent résoudre le problème ...

0
Hossein Karami

Mon application a eu le même problème. Mais ce n'était pas autre chose que d'afficher une liste de cartes et du texte dessus. Rien ne court en arrière-plan. Mais après une enquête, il a été constaté que l’image définie pour l’arrière-plan de la carte était à l'origine de ce problème, même si elle était petite (350 Ko). Puis j'ai converti l'image en images 9patch en utilisant http://romannurik.github.io/AndroidAssetStudio/index.html .
Cela a fonctionné pour moi.

0
naamadheya

Après avoir fait beaucoup de R & D sur cette question, j'ai eu la solution,

Dans mon cas, j'utilise un service qui s'exécute toutes les 2 secondes et avec le runonUIThread, je me demandais si le problème existait mais pas du tout ... Le prochain problème que j'ai découvert est que j'utilise Image de grande taille dans may App et c'est le problème.

J'ai enlevé les images et mis de nouvelles images.

Conclusion: - Examinez dans votre code si un fichier brut que vous utilisez est de grande taille. 

0
Hector Morris