2016-03-23 7 views
0

(HINWEIS: Ich schreibe meine Frage neu, weil meine erste Version ungenau war).android.os.Handler.removeMessages funktioniert nicht beim Verpacken Wert als msg.obj

den folgenden Code Gegeben:

Handler handler = new Handler(); 
Message msg = handler.obtainMessage(12345, 67890L); 
handler.sendMessageDelayed(message, 10000); 
... 
handler.removeMessages(12345, 67890L); 

Das Problem ist, dass die Nachricht feuert noch 10 Sekunden, nachdem ich es geschickt!

Warum ist handler.removeMessages nicht die Nachricht entfernen?

Antwort

1

Das Problem ist das automatische Boxen des langen zu einem langen Objekt.

Im Debugger von MessageQueue void removeMessages(Handler h, int what, Object object):

638: // Remove all messages after front. 
639: while (p != null) { 
640:  Message n = p.next; 
641:  if (n != null) { 
642:   if (n.target == h && n.what == what 
643:    && (object == null || n.obj == object)) { 
644:    Message nn = n.next; 
645:    n.recycleUnchecked(); 
646:    p.next = nn; 
647:    continue; 
648:   } 
649:  } 
650:  p = n; 
651: } 

In Zeile 643:

object = {[email protected]} "67890" 
n.obj = {[email protected]} "67890" 

in meinem Fall also nicht der Vergleich immer, weil es Fälle vergleicht, und meine Box-Wert Instanzen sind immer anders.

Dennoch würde ich die Unter-behandelt die Umsetzung von removeMessages erwartet, die folgenden zu sein:

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

Meine Lösung ist, um so etwas zu tun:

LongSparseArray<Long> objects = new LongSparseArray<>(); 
Handler handler = new Handler(); 

void sendMessageDelayed(int what, long key, long delayMillis) 
{ 
    Object obj = key; 
    objects.put(key, object); 

    Message msg = handler.obtainMessage(what, obj); 
    handler.sendMessageDelayed(message, delayMillis); 
} 

void removeMessages(int what, long key) 
{ 
    Object obj = objects.remove(key); 
    if (obj != null) 
    { 
     handler.removeMessages(what, key); 
    } 
} 

sendMessageDelayed(12345, 67890L, 10000); 
... 
removeMessages(12345, 67890L); 

Pv