¿Cómo eliminar todas las devoluciones de llamada de un controlador?

Tengo un controlador de mi subactividad que fue llamado por la actividad principal. Las postDelay utilizan este Manejador para postDelay algunos Runnables, y no puedo gestionarlos. Ahora, en el evento onStop , necesito eliminarlos antes de terminar la actividad (de alguna manera llamé a finish() , pero aún así se llama una y otra vez). ¿Hay alguna manera de eliminar todas las devoluciones de llamada de un controlador?

En mi experiencia, llamar esto funcionó muy bien.

 handler.removeCallbacksAndMessages(null); 

En los documentos para removeCallbacksAndMessages dice …

Elimine las publicaciones pendientes de devoluciones de llamada y los mensajes enviados cuyo obj es token. Si token es null , se eliminarán todas las devoluciones de llamada y mensajes.

Para cualquier instancia específica de Runnable , llame a Handler.removeCallbacks() . Tenga en cuenta que utiliza la instancia de Runnable para determinar qué devoluciones de llamadas debe anular el registro, por lo que si está creando una nueva instancia cada vez que se realiza una publicación, debe asegurarse de tener referencias al Runnable exacto para cancelar. Ejemplo:

 Handler myHandler = new Handler(); Runnable myRunnable = new Runnable() { public void run() { //Some interesting task } }; 

Puede llamar a myHandler.postDelayed(myRunnable, x) para publicar otra callback a la cola de mensajes en otros lugares de su código y eliminar todas las devoluciones de llamada pendientes con myHandler.removeCallbacks(myRunnable)

Desafortunadamente, no puede simplemente “borrar” toda la MessageQueue de un Handler , incluso si hace una solicitud para el objeto MessageQueue asociado porque los métodos para agregar y eliminar elementos están protegidos por paquetes (solo las clases dentro del paquete android.os pueden llamar ellos). Es posible que deba crear una subclase de Handler delgada para administrar una lista de Runnable a medida que se publican / ejecutan … o consulte otro paradigma para pasar sus mensajes entre cada Activity

¡Espero que ayude!

Si no tiene las referencias de Runnable, en la primera callback, obtenga el obj del mensaje y use removeCallbacksAndMessages () para eliminar todas las devoluciones de llamada relacionadas.

Definir un nuevo controlador y ejecutable:

 private Handler handler = new Handler(Looper.getMainLooper()); private Runnable runnable = new Runnable() { @Override public void run() { // Do what ever you want } }; 

Publicación de llamada retrasada:

 handler.postDelayed(runnable, sleep_time); 

Elimine su callback de su controlador:

 handler.removeCallbacks(runnable); 

En realidad, hay un pequeño pero importante punto aquí. Debe definir un Handler y un Runnable solo la primera vez. En realidad removeCallbacks(runnable) funciona correctamente, pero si los defines cada vez, es posible que no los manejes.

Forma falsa

  public class FooActivity extends Activity { private void handleSomething(){ Handler handler = new Handler(); Runnable runnable = new Runnable() { @Override public void run() { doIt(); } }; if(shouldIDoIt){ //doIt() works after 3 seconds. handler.postDelayed(runnable, 3000); } else { handler.removeCallbacks(runnable); } } public void onClick(View v){ handleSomething(); } } 

Si llamas al método doIt() onClick(..) , nunca dejas de llamar al método doIt() antes de llamar. Porque cada vez crea un new Runnable y new Runnable instancias new Runnable . De esta forma, ha perdido las referencias necesarias que pertenecen al controlador y a las instancias ejecutables .

Verdadera manera

  public class FooActivity extends Activity { Handler handler = new Handler(); Runnable runnable = new Runnable() { @Override public void run() { doIt(); } }; private void handleSomething(){ if(shouldIDoIt){ //doIt() works after 3 seconds. handler.postDelayed(runnable, 3000); } else { handler.removeCallbacks(runnable); } } public void onClick(View v){ handleSomething(); } } 

De esta forma, no pierde referencias reales y removeCallbacks(runnable) funciona correctamente.

La oración clave es que ‘defínalos como globales en tu Activity o Fragment lo que usas’ .