La aplicación puede estar haciendo demasiado trabajo en su hilo principal

379

Soy nuevo en el entorno Android SDK / API. Es el primero que intento dibujar un diagrama / gráfico. Intenté ejecutar diferentes tipos de códigos de muestra del emulador usando 3 bibliotecas gratuitas diferentes, no se muestra nada en la pantalla de diseño. El logcat está repitiendo el siguiente mensaje:

 W / Trace (1378): valor inesperado de nativeGetEnabledTags: 0
 Yo / Coreógrafo (1378): ¡Salteé 55 cuadros! La aplicación puede estar haciendo demasiado trabajo en su hilo principal.

El problema no persistió y el gráfico funcionó cuando ejecuté un código de muestra relacionado con una copia de evaluación de una biblioteca con licencia.

usuario2038135
fuente
2
¿Estás dibujando tus gráficos en un hilo separado?
Areks
Gracias por tu comentario, edité la pregunta para que quede más clara. La actividad cuando se ejecuta muestra que estoy ejecutando una actividad que no tiene diseño, su diseño => muestra una pantalla en blanco.
usuario2038135
1
@Areks No, no estoy usando un hilo separado.
usuario2038135
1
Creo que debería, no se recomienda en absoluto realizar operaciones largas en el hilo principal, ya que eso congela toda la aplicación, puede leer cómo usar hilos aquí: stackoverflow.com/questions/3391272/… Ignore el "código que debe hacer la solicitud HTTP "y simplemente ejecute sus operaciones potencialmente largas allí.
Areks
1
Por qué no intentas buscar, encontrarás información sobre el coreógrafo. Le recomiendo que lea esta respuesta: stackoverflow.com/questions/11266535/…
Gabriel Esteban

Respuestas:

479

tomado de: Android UI: arreglando marcos omitidos

Cualquiera que comience a desarrollar una aplicación para Android ve este mensaje en logcat "Coreógrafo (abc): ¡Se omiten los marcos xx! La aplicación puede estar haciendo demasiado trabajo en su hilo principal ". Entonces, ¿qué significa en realidad, por qué debería preocuparse y cómo resolverlo?

Lo que esto significa es que su código tarda mucho en procesarse y se omiten los marcos debido a ello, tal vez debido a un procesamiento pesado que está haciendo en el corazón de su aplicación o acceso a la base de datos o cualquier otra cosa que haga que el hilo detente por un rato.

Aquí hay una explicación más detallada:

Choreographer permite que las aplicaciones se conecten a la sincronización virtual y sincronice correctamente las cosas para mejorar el rendimiento.

Las animaciones de vista de Android utilizan internamente a Choreographer con el mismo propósito: cronometrar adecuadamente las animaciones y posiblemente mejorar el rendimiento.

Dado que se informa a Choreographer sobre todos los eventos vsync, puedo decir si uno de los Runnables que pasó el Choreographer.post * apis no termina en el tiempo de un cuadro, lo que hace que se omitan los cuadros.

En mi opinión, el Coreógrafo solo puede detectar el salto de cuadro. No tiene forma de decir por qué sucede esto.

El mensaje "La aplicación puede estar haciendo demasiado trabajo en su hilo principal". Podría ser engañoso.

fuente: Significado de los mensajes del coreógrafo en Logcat

¿Por qué deberías preocuparte?

Cuando aparece este mensaje en el emulador de Android y el número de fotogramas omitidos es bastante pequeño (<100), puede apostar con seguridad de que el emulador es lento, lo que sucede casi todas las veces. Pero si el número de cuadros se omitió y es grande y del orden de más de 300, entonces puede haber algunos problemas serios con su código. Los dispositivos Android vienen en una amplia gama de hardware a diferencia de los dispositivos iOS y Windows. La RAM y la CPU varían y si desea un rendimiento razonable y una experiencia de usuario en todos los dispositivos, entonces debe solucionarlo. Cuando se omiten los marcos, la interfaz de usuario es lenta y lenta, lo que no es una experiencia de usuario deseable.

Como arreglarlo

Arreglar esto requiere identificar nodos donde hay o puede ocurrir una larga duración del procesamiento. La mejor manera es hacer todo el procesamiento sin importar cuán pequeño o grande en un hilo separado del hilo principal de la interfaz de usuario. Entonces, ya sea accediendo a datos desde la base de datos SQLite o haciendo algunos cálculos matemáticos o simplemente ordenando una matriz: hágalo en un hilo diferente

Ahora hay un problema aquí: creará un nuevo subproceso para realizar estas operaciones y cuando ejecute su aplicación, se bloqueará diciendo "Solo el subproceso original que creó una jerarquía de vistas puede tocar sus vistas". Necesita saber este hecho de que la interfaz de usuario en Android se puede cambiar por el hilo principal o solo por el hilo de la interfaz de usuario. Cualquier otro hilo que intente hacerlo, falla y falla con este error. Lo que debe hacer es crear un nuevo Ejecutable dentro de runOnUiThread y dentro de este ejecutable debe realizar todas las operaciones relacionadas con la IU. Encuentra un ejemplo aquí .

Entonces tenemos Thread and Runnable para procesar datos fuera de Thread principal, ¿qué más? Hay AsyncTask en Android que permite realizar procesos a largo plazo en el hilo de la interfaz de usuario. Esto es lo más útil cuando sus aplicaciones están basadas en datos o en aplicaciones web o utilizan interfaces de usuario complejas, como las que se crean con Canvas. El poder de AsyncTask es que permite hacer cosas en segundo plano y una vez que haya terminado el procesamiento, simplemente puede realizar las acciones necesarias en la interfaz de usuario sin causar ningún efecto rezagado. Esto es posible porque AsyncTask se deriva del subproceso de IU de Activity: todas las operaciones que realiza en UI a través de AsyncTask se realizan en un subproceso diferente del subproceso de IU principal, sin obstáculos para la interacción del usuario.

Entonces, esto es lo que necesita saber para crear aplicaciones de Android fluidas y, hasta donde sé, cada principiante recibe este mensaje en su consola.

Jorgesys
fuente
41
Solo tengo una aplicación en la que si hago clic en un botón, la imagen de fondo del botón cambia y el botón no se puede hacer clic. ¿Cómo estoy haciendo demasiado trabajo :(
Remian8985
1
@ Remian8985: el cambio de la imagen de fondo para el botón (suponiendo que esté descargando esta imagen) debe realizarse en AsyncTask, es decir, realizar esa operación de descarga de fondo y publicar el resultado en el hilo de la interfaz de usuario (devuelva la imagen). Ver enlace de
BenJaminSila
11
@BenJaminSila cambiando de fondo en AsyncTask? De Verdad?
usuario25
11
@ user25 "suponiendo que esté descargando esta imagen"
forresthopkinsa
"Cuando aparece este mensaje en el emulador de Android y el número de fotogramas omitidos es bastante pequeño (<100), entonces puede apostar con seguridad de que el emulador es lento" ¿Esto todavía se aplica hoy? Los emuladores se están volviendo bastante rápidos, ¿verdad?
Robin Dijkhof
243

Como otros respondieron anteriormente, "¡Se saltaron 55 fotogramas!" significa que hay un procesamiento pesado en su aplicación.

Para mi caso, no hay un proceso pesado en mi solicitud. Revisé todo doble y triplemente y eliminé esos procesos que creo que fueron un poco pesados.

Eliminé Fragmentos, Actividades, Bibliotecas hasta que solo quedó el esqueleto. Pero aún así el problema no desapareció. Decidí verificar los recursos y descubrí que algunos íconos y antecedentes que uso son bastante grandes, ya que olvidé verificar el tamaño de esos recursos.

Por lo tanto, mi sugerencia es que si ninguna de las respuestas anteriores ayuda, también puede verificar el tamaño de los archivos de recursos.

Sithu
fuente
1
A mi también me sirvió. Tenía una aplicación que estaba haciendo muy poco trabajo pero era lenta y lenta. Seguí recibiendo registros de cuadros omitidos. Una vez que eliminé el fondo de mi actividad, todo estuvo bien. ¡Gracias!
akrabi
Gran respuesta, creo que este fue exactamente mi problema. Probé un montón de otras soluciones (bastante complicadas) y la aplicación era igual de lenta. Eliminé todos los servicios web e intenté optimizar mi código hasta el hueso. No funcionó, entonces vi esto. Tan pronto como eliminé mi imagen de fondo (la imagen más grande que tengo) la aplicación funciona casi tan rápido como puedes hacer clic, incluso con el viejo código "lento".
M Barbosa
¡me has alegrado el día!
Nicolas Mastromarino
:) Eres un genio absoluto.
Metin Ilhan
@batsheva no es necesario tener 1 KB. Depende de sus necesidades, digamos que necesita una imagen más clara, puede usar una resolución más alta, pero asegúrese de dividirla en diferentes tamaños en las diferentes carpetas de recursos.
Sithu
61

Yo también tuve el mismo problema.
El mío fue un caso en el que estaba usando una imagen de fondo que estaba en dibujables. Esa imagen en particular era de aproximadamente 130 KB y se usaba durante la pantalla de inicio y la página de inicio en mi aplicación de Android.

Solución : acabo de cambiar esa imagen en particular a la carpeta drawables-xxx de drawables y pude liberar mucha memoria ocupada en el fondo y los marcos omitidos ya no se omiten.

Actualización Use la carpeta de recursos dibujables 'nodp' para almacenar archivos dibujables en segundo plano.
¿Tendrá prioridad una carpeta dibujable calificada para densidad o drawable-nodpi?

Prakhar1001
fuente
77
¡Moví mi imagen de fondo grande de dibujable a mimap-xxxhdpi y funcionó!
bgplaya
Tu ayudaste mucho. Gracias
N.Droid
2
Esta solución está haciendo el truco. Estoy usando la carpeta drawable-xxxhdpien lugar drawablede lo reduce drásticamente la memoria usada (~ 70 por ciento menos). También es bueno saber que las pantallas con el mismo tamaño varían en tamaño de DPI. La relación en píxeles entre ellos es ldpi = 1:0.75, mdpi = 1:1, hdpi = 1:1.5, xhdpi = 1:2, xxhdpi = 1:3, xxxhdpi = 1:4. Al usar la drawable-xxxhdpicarpeta, permite reducir las imágenes al tamaño de pantalla de su dispositivo, lo que reduce el consumo de memoria y CPU.
Timo Bähr
2
Mover imágenes de drawablea drawable-nodpievita que se obtenga la aplicación Out of Memory Error.
Shruti
Oh dios mio ... gracias! Tenía una imagen dentro de la carpeta dibujable y esto hizo que mi aplicación fuera más lenta (¡aunque la imagen era de solo 100 kb!). Después de generar los archivos drawable-xxx (utilicé el Importador de Android Drawable) mi aplicación es muy rápida. ¡Muchas gracias!
error1337
20

Otra causa común de demoras en el subproceso de interfaz de usuario es el acceso a las preferencias compartidas. Cuando llama a uno PreferenceManager.getSharedPreferencesy otros métodos similares por primera vez, el archivo .xml asociado se carga inmediatamente y se analiza en el mismo hilo .

Una de las mejores maneras de combatir este problema es desencadenar la primera carga SharedPreference desde el subproceso en segundo plano, que se inicia lo antes posible (por ejemplo, desde onCreate su clase de aplicación). De esta manera, el objeto de preferencia ya puede estar construido para cuando quiera usarlo.

Desafortunadamente, a veces es necesario leer los archivos de preferencias durante las primeras fases del inicio (por ejemplo, en la Actividad inicial o incluso en la Aplicación en sí). En tales casos, todavía es posible evitar el bloqueo de la IU mediante el uso MessageQueue.IdleHandler. Haga todo lo demás que necesita realizar en el hilo principal, luego instale IdleHandler para ejecutar el código una vez que su Actividad se haya dibujado por completo. En ese Runnable, debería poder acceder a SharedPreferences sin retrasar demasiadas operaciones de dibujo y hacer que Choreographer sea infeliz.

usuario1643723
fuente
1
Para este caso, debe preferir el método apply () en lugar de commit (). El método apply () no puede bloquear la interfaz de usuario. Puede mirar desde aquí developer.android.com/training/data-storage/shared-preferences
Emre Gürses
16

Intente utilizar las siguientes estrategias para mejorar el rendimiento de su aplicación:

  • Utilice la programación de subprocesos múltiples si es posible. Los beneficios de rendimiento son enormes, incluso si su teléfono inteligente tiene un núcleo (los subprocesos pueden ejecutarse en diferentes núcleos, si el procesador tiene dos o más). Es útil separar la lógica de la aplicación de la interfaz de usuario. Use hilos de Java, AsyncTask o IntentService. Mira esto .
  • Lea y siga los consejos de rendimiento misceláneo del sitio web de desarrollo de Android. Mira aquí .
MigDus
fuente
3
su primer enlace requiere que "... tenga una cuenta validada ..." para acceder a ella.
chornge
9

Yo tuve el mismo problema. Android Emulator funcionó perfectamente en Android <6.0. Cuando utilicé el emulador Nexus 5 (Android 6.0), la aplicación funcionó muy lentamente conI/Choreographer: Skipped frames en los registros.

Entonces, resolví este problema cambiando la hardwareAcceleratedopción de archivo Manifiesto para que me truegustara esto:

<?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>
phen0menon
fuente
8

No soy un experto, pero recibí este mensaje de depuración cuando quería enviar datos desde mi aplicación de Android a un servidor web. Aunque utilicé la clase AsyncTask e hice la transferencia de datos en segundo plano, para recuperar los datos del resultado del servidor utilicé el método get () de la clase AsyncTask que hace que la IU sea sincrónica, lo que significa que su IU estará esperando demasiado tiempo. Entonces, mi consejo es hacer que su aplicación realice todas las tareas orientadas a la red en un hilo separado.

saba
fuente
6

Optimice sus imágenes ... No use imágenes de más de 100 KB ... La carga de imágenes toma demasiada CPU y hace que su aplicación se bloquee.

HarshitG
fuente
44
Disminuya el tamaño de la imagen, ya sea por código java o use Photoshop para recortar imágenes ... también comprima las imágenes con compressor.io
HarshitG
5

Yo tuve el mismo problema. En mi caso, tenía 2 diseños relativos anidados. RelativeLayout siempre tiene que hacer dos pases de medida. Si anida RelativeLayouts, obtendrá un algoritmo de medición exponencial.

Radoslav
fuente
4

Esto suele suceder cuando se ejecutan grandes procesos en el hilo principal. está bien omitir marcos de menos de 200. pero si tiene más de 200 marcos omitidos, puede ralentizar el hilo de la interfaz de usuario de la aplicación. lo que puede hacer es hacer estos procesos en un nuevo subproceso llamado subproceso de trabajo y después de eso, cuando desee acceder y hacer algo con el subproceso de interfaz de usuario (por ejemplo, hacer algo con vistas, findView, etc.) puede usar el controlador o runOnUiThread (Me gusta más) para mostrar los resultados del procesamiento. Esto resuelve absolutamente el problema. El uso de hilos de trabajo es muy útil o incluso debe usarse cuando se trata de estos casos.

Hossein Karami
fuente
1

Yo tuve el mismo problema. Cuando ejecuté el código en otra computadora, funcionó bien. En el mío, sin embargo, mostraba "La aplicación puede estar haciendo demasiado trabajo en su hilo principal".

Resolví mi problema reiniciando Android studio [Archivo -> Cachés invalidados / Reiniciar -> haga clic en "Invalidar y reiniciar"].

sonida
fuente
No sé por qué funcionó tu solución. De todos modos gracias.
Bhuvanesh BS
1

En mi caso, fue porque accidentalmente había establecido un punto de interrupción en un método. Una vez que lo borré, el mensaje desapareció y el rendimiento mejoró mucho.

FractalBob
fuente
0

Mi aplicación tuvo el mismo problema. Pero no estaba haciendo más que mostrar una lista de tarjetas y texto en él. Nada corriendo en el fondo. Pero luego, después de una investigación, se descubrió que la imagen configurada para el fondo de la tarjeta estaba causando esto, a pesar de que era pequeña (350 kb). Luego convertí la imagen a imágenes de 9 parches usando http://romannurik.github.io/AndroidAssetStudio/index.html .
Esto funcionó para mí.

naamadheya
fuente
0

Después de hacer mucho I + D sobre este tema, obtuve la solución,

En mi caso, estoy usando un servicio que se ejecutará cada 2 segundos y con runonUIThread, me preguntaba si el problema estaba allí pero no del todo. El siguiente problema que encontré es que estoy usando una imagen grande en la aplicación de mayo y ese es el problema.

Eliminé las imágenes y configuré nuevas imágenes.

Conclusión: - Mira en tu código si hay algún archivo sin formato que estés usando que sea de gran tamaño.

Héctor Morris
fuente
0

Primero lea la advertencia. Dice más carga en el hilo principal. Entonces, lo que tiene que hacer es ejecutar funciones con más trabajo en un hilo.

de_billa_
fuente
-1

Tuve el mismo problema al desarrollar una aplicación que utiliza muchos archivos png dibujables en el diseño de cuadrícula. También intenté optimizar mi código lo más posible ... pero no funcionó para mí ... Luego intenté reducir el tamaño de esos png ... y supongo que funciona absolutamente bien ... Así que mi sugerencia es reducir tamaño de los recursos extraíbles, si los hay.

Shubham Ranakoti
fuente