Pregunta

tengo un Manipulador de mi subactividad que fue llamado por el principal Actividad. Este controlador es utilizado por subclases para postDelay Algunos Runnables, y no puedo manejarlos. Ahora, en el onStop evento, necesito eliminarlos antes de terminar la actividad (de alguna manera llamé finish(), pero todavía llama una y otra vez). ¿Hay alguna forma de eliminar todas las devoluciones de llamada de un controlador?

¿Fue útil?

Solución

¡En mi experiencia, llamar a esto funcionó muy bien!

handler.removeCallbacksAndMessages(null);

En los documentos para retirar y los modelos de mando, dice ...

Elimine cualquier publicación pendiente de devoluciones de llamada y envió mensajes cuyo obj sea token. Si la token es null, se eliminarán todas las devoluciones de llamada y mensajes.

Otros consejos

Para cualquier específico Runnable instancia, llamar Handler.removeCallbacks(). Tenga en cuenta que usa el Runnable instancia misma para determinar qué devoluciones de llamada no registrar, por lo que si está creando una nueva instancia cada vez que se realiza una publicación, debe asegurarse de tener referencias a los exactos Runnable cancelar. Ejemplo:

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

Puedes llamar myHandler.postDelayed(myRunnable, x) Para publicar otra devolución de llamada 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 puedes simplemente "despejar" todo MessageQueue para Handler, incluso si hace una solicitud para el MessageQueue Objeto asociado con él porque los métodos para agregar y eliminar elementos están protegidos por el paquete (solo las clases dentro del paquete Android.os pueden llamarlos). Puede que tenga que crear un delgado Handler subclase para administrar una lista de Runnables como se publican/ejecutan ... o mire otro paradigma para transmitir sus mensajes entre cada uno Activity

¡Espero que ayude!

Si no tiene las referencias de ejecución, en la primera devolución de llamada, obtenga el OBJ del mensaje y use RemoVecallBacksandMessages () Para eliminar todas las devoluciones de llamada relacionadas.

Defina un nuevo manejador 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);

Retire su devolución de llamada de su controlador:

handler.removeCallbacks(runnable);

Tenga en cuenta que uno debe definir un Handler y un Runnable En el alcance de la clase, para que se cree una vez.removeCallbacks(Runnable) Funciona correctamente a menos que uno los define varias veces. Mire los siguientes ejemplos para una mejor comprensión:

Forma incorrecta:

    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 onClick(..) Método, nunca te detienes doIt() Método llamar antes de llamar. Porque cada vez crea new Handler y new Runnable instancias. De esta manera, perdiste las referencias necesarias que pertenecen a manipulador y corredor instancias.

Forma correcta:

 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 manera, no perdió referencias reales y removeCallbacks(runnable) funciona con éxito.

La oración clave es que 'Defínalos como globales en tu Activity o Fragment lo que usas'.

Como josh527 dijo, handler.removeCallbacksAndMessages(null); puede trabajar.
¿Pero por qué?
Si observa el código fuente, puede entenderlo más claramente. Hay 3 tipos de método para eliminar las devoluciones de llamada/mensajes del controlador (el Messagequeue):

  1. Eliminar por devolución de llamada (y token)
  2. eliminar por mensaje.
  3. Eliminar por token

Handler.java (deje algún método de sobrecarga)

/**
 * Remove any pending posts of Runnable <var>r</var> with Object
 * <var>token</var> that are in the message queue.  If <var>token</var> is null,
 * all callbacks will be removed.
 */
public final void removeCallbacks(Runnable r, Object token)
{
    mQueue.removeMessages(this, r, token);
}

/**
 * Remove any pending posts of messages with code 'what' and whose obj is
 * 'object' that are in the message queue.  If <var>object</var> is null,
 * all messages will be removed.
 */
public final void removeMessages(int what, Object object) {
    mQueue.removeMessages(this, what, object);
}

/**
 * Remove any pending posts of callbacks and sent messages whose
 * <var>obj</var> is <var>token</var>.  If <var>token</var> is null,
 * all callbacks and messages will be removed.
 */
public final void removeCallbacksAndMessages(Object token) {
    mQueue.removeCallbacksAndMessages(this, token);
}

Messagequeue.java Haz el trabajo real:

void removeMessages(Handler h, int what, Object object) {
    if (h == null) {
        return;
    }

    synchronized (this) {
        Message p = mMessages;

        // Remove all messages at front.
        while (p != null && p.target == h && p.what == what
               && (object == null || p.obj == object)) {
            Message n = p.next;
            mMessages = n;
            p.recycleUnchecked();
            p = n;
        }

        // Remove all messages after front.
        while (p != null) {
            Message n = p.next;
            if (n != null) {
                if (n.target == h && n.what == what
                    && (object == null || n.obj == object)) {
                    Message nn = n.next;
                    n.recycleUnchecked();
                    p.next = nn;
                    continue;
                }
            }
            p = n;
        }
    }
}

void removeMessages(Handler h, Runnable r, Object object) {
    if (h == null || r == null) {
        return;
    }

    synchronized (this) {
        Message p = mMessages;

        // Remove all messages at front.
        while (p != null && p.target == h && p.callback == r
               && (object == null || p.obj == object)) {
            Message n = p.next;
            mMessages = n;
            p.recycleUnchecked();
            p = n;
        }

        // Remove all messages after front.
        while (p != null) {
            Message n = p.next;
            if (n != null) {
                if (n.target == h && n.callback == r
                    && (object == null || n.obj == object)) {
                    Message nn = n.next;
                    n.recycleUnchecked();
                    p.next = nn;
                    continue;
                }
            }
            p = n;
        }
    }
}

void removeCallbacksAndMessages(Handler h, Object object) {
    if (h == null) {
        return;
    }

    synchronized (this) {
        Message p = mMessages;

        // Remove all messages at front.
        while (p != null && p.target == h
                && (object == null || p.obj == object)) {
            Message n = p.next;
            mMessages = n;
            p.recycleUnchecked();
            p = n;
        }

        // Remove all messages after front.
        while (p != null) {
            Message n = p.next;
            if (n != null) {
                if (n.target == h && (object == null || n.obj == object)) {
                    Message nn = n.next;
                    n.recycleUnchecked();
                    p.next = nn;
                    continue;
                }
            }
            p = n;
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top