¿Por qué mi aplicación Android salta los marcos cuando se llama a Thread.sleep?
Estoy escribiendo una aplicación de Android que necesita mostrar algún texto para unos pocos milésimas de segundo, luego en blanco de nuevo. Lo que tengo ahora es que muestra el texto, a continuación, utilizando Thread.sleep, a continuación, establecer el texto de nuevo a null. En cambio, lo que sucede es que al presionar el botón, la aplicación se bloquea por el tiempo establecido, el texto nunca aparece, y el logcat dice: "Saltará xxx marcos! La aplicación puede estar haciendo demasiado trabajo en su hilo principal". ¿Qué está pasando, y hay una mejor manera de hacer las cosas?
- Desactivar el tiempo de espera de la pantalla Teléfono / tablet Android
- Confusión sobre el ciclo de vida de la actividad de Android
- Android, obteniendo la señal de intensidad (PhoneStateListener) mientras el dispositivo está en modo de suspensión
- Android sleep () sin bloquear la interfaz de usuario
- Detener una aplicación de Android con Phonegap
- SystemClock.sleep () vs. Thread.sleep () mientras espera un bucle de semáforo
- Toast no se mostrará antes de intentar / catch Thread.sleep ()
- Función Android Sleep / Wait / Delay
- Cómo despertar el teléfono Android de dormir?
- Acceso a la red cuando el teléfono Android está dormido
- Despertar un hilo de dormir - interrupción () versus "dividir" el sueño en varios sueños
- ¿Cómo dormir hilo en Xamarin android y ios?
- La captura de pulsaciones de teclas cuando el teléfono Android está en modo de suspensión profunda
Trate de usar un runnable.
private Handler mHandler = new Handler(); //code to make text appear... mHandler.postDelayed(makeTextDisapear , 3000); // Replace 3000 with the number of milliseconds you want the text to display. private Runnable makeTextDisapear = new Runnable() { public void run() { // code to make text dissapear } };
Mientras que otras respuestas ayudan a resolver su problema, su pregunta fue también por qué sucede esto:
Llamar cualquiera de los métodos estáticos Thread.sleep()
coloca el Thread del cual se invocó el método en un estado de pausa para (aproximadamente) la cantidad de tiempo que especifica (no se garantiza que coincida exactamente con el tiempo especificado).
En Android, las operaciones de Ui tienen que realizarse en el hilo "ui" principal, ya que el framework Ui no está diseñado para ser seguro de subprocesos. Es decir, cuando se establece el texto de un TextView
, tiene que invocar textView.setText(...)
en el subproceso principal. setText
enviará un mensaje al Looper
principal para volver a diseñar e invalidar el TextView (y los padres). En algún momento en el futuro cercano, esos mensajes serán procesados y la jerarquía de la vista será actualizada.
setText
no hace este trabajo directamente porque esta carga de trabajo es pesada, y hacerlo directamente no permitiría que el marco para agrupar dichas solicitudes.
Si invoca Thread.sleep(...)
, está poniendo el hilo ui principal en un estado de pausa, sin embargo, es este hilo el que normalmente realizará el re-diseño y la invalidación de TextView y los padres.
Android quiere ser capaz de hacer un nuevo marco (si algo ha cambiado) en menos de 16ms para mantener un mayor de 60fps. Si su hilo principal está haciendo algo intensivo, o se detiene (por dormir) durante un tiempo significativo que podría amenazar a los 16 ms, el mensaje de error que está viendo se publica en logcat.
Mientras que en Lollipop la representación real se realiza en su propio hilo de render, todavía necesita actualizaciones oportunas del hilo principal.
En cuanto a cómo solucionar esto, vea la respuesta de Jason, o, alternativamente, publicar un retrasado ejecutables a la vista en sí (en lugar de una instancia de manejador directamente) mediante
textView.setText("show me!"); textView.postDelayed(new Runnable() { public void run() { textView.setText(""); } }, 30);
Si esto ocurre regularmente, evite la asignación del Runnable
cada vez manteniéndolo como un campo.
Tenga en cuenta que en cualquier caso, la creación de una clase interna anónima (el Runnable
) tiene el potencial de pérdida de memoria de la actividad, pero eso es una historia diferente.
- Actualización del ejemplo HelloJni
- ImageButton de nivelación semitransparente con nivelación de transparencia