RemoveCallbacks no se detiene runnable
Estoy llamando de un método:
myHandler.postDelayed(mMyRunnableHide, 6000);
Que llama:
- Tomando un cómputo pesado del subproceso de la interfaz de usuario de Android
- Cómo pasar o asignar un valor obtenido en un runOnUiThread
- ¿Es este hilo seguro?
- Android OpenGL gameloop fuera de OnFrame
- Android: ¿Cómo puedo detener Runnable?
public Runnable mMyRunnableHide = new Runnable() { public void run() { mTextDisplay.setText(""); DisplayX(); } };
Si se hace clic en un botón de la pantalla, quiero detener la ejecución:
Button next = (Button) findViewById(R.id.Breaction); next.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { myHandler.removeCallbacks(mMyRunnableHide); mTextDisplay.setText(""); DisplayX(); } }); }
El removeecallbacks no está deteniendo el runnable. ¿Qué estoy haciendo mal? ¿Estoy usando el método correcto? Sólo quiero que el runnable "no se ejecute" cuando el usuario hace clic en el botón.
Gracias por cualquier ayuda.
- ¿Existe ya una clase StopWatch para android y por qué no funciona mi implementación?
- ¿Cómo poner un runnable en paquete?
- Cómo implementar una cola de runnables
- Contexto dentro de un Runnable
- Actualizar la interfaz de usuario de Android desde un subproceso de otra clase
- Actualización de la interfaz de usuario desde un servicio (mediante un controlador?)
- Android: Múltiples temporizadores en un ListView con manejador y ejecutables. 2 Problemas
- Mejor manera de esperar a que retrofit2 termine antes de continuar async
Parece que removeCallbacks(..)
sólo detiene los mensajes pendientes (Runnables). Si su runnable ya ha comenzado, entonces no hay parada (al menos no de esta manera).
Alternativamente, puede extender la clase Runnable y darle algún tipo de interruptor kill de esta manera:
public class MyRunnable implements Runnable { private boolean killMe = false; private void run() { if(killMe) return; /* do your work */ } private void killRunnable() { killMe = true; } }
Esto sólo evitará que se inicie, pero en ocasiones puede comprobar killMe
y rescatar. Si está haciendo un bucle en el runnable (como algún tipo de hilo de fondo) puede decir:
while(!killMe) { /* do work */ }
Espero que esto ayude
EDIT Yo sólo quería publicar una actualización sobre esto. Desde este post original, Google ha llegado con una gran clase llamada AsyncTask que maneja todas estas cosas para usted. Cualquiera que lea esto realmente debe mirar en él porque es la manera correcta de hacer las cosas.
Puedes leer sobre esto aquí
Aquí hay otra manera de lograr lo que mtmurdock está describiendo. Esta clase permitirá la edición de variables de instancia en cualquier clase que su Runnable se define como una clase interna anónima.
package support; /** * Runnable that can be stopped from executing * @author JTRONLABS */ public abstract class KillableRunnable implements Runnable{ private boolean isKilled=false; /** * Instead of Overriding run(), override this method to perform a Runnable operation. * This will allow editing instance variables in the class that this Runnable is defined */ public abstract void doWork(); //The handler that posts this Runnable will call this method. //By default, check if it has been killed. doWork() will now be the method //override to implement this Runnable @Override final public void run(){ if(!isKilled){ doWork(); } } final public void kill(){ isKilled=true; } }
Handler.removeCallback
es síncrono y funcionará muy bien siempre:
-
postDelayed
apostDelayed
siempre en el hilo principal. - Usted llama a
removeCallback
siempre en el hilo principal - No
postDelayed
llamar apostDelayed
después de haber eliminado las devoluciones de llamada.
Así que en su caso removeCallbacks
se llama desde un manejador de botones, que se ejecuta en el hilo principal. Pero no mostró en su código el punto desde el que llama a postDelayed
. Si lo llamas desde un hilo de fondo es donde está tu problema.
Si está seguro de no llamar a ninguno de estos métodos de los subprocesos de fondo, y el orden de las llamadas es correcto, es posible que deje las tareas no canceladas de forma invariable viva debido a la recreación de la actividad en los cambios de configuración. Siempre asegúrese de llamar a removeCallbacks
nuevo en el método onDestroy
para evitar este tipo de problemas.
- ¿Cómo obtener un cuerpo de respuesta para la excepción de actualización?
- No se puede localizar un Java Runtime Android Studio Robolectric