当装箱值类型为 msg.obj 时,android.os.Handler.removeMessages 不起作用
android.os.Handler.removeMessages doesn't work when boxing value type as msg.obj
(注意:我正在重写我的问题,因为我的第一个版本不准确)。
给定以下代码:
Handler handler = new Handler();
Message msg = handler.obtainMessage(12345, 67890L);
handler.sendMessageDelayed(message, 10000);
...
handler.removeMessages(12345, 67890L);
问题是消息在我发送 10 秒后仍然触发!
为什么 handler.removeMessages
不删除邮件?
问题是 long 到 Long 对象的自动装箱。
在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: }
第 643 行:
object = {java.lang.Long@4686} "67890"
n.obj = {java.lang.Long@4688} "67890"
所以,在我的例子中,比较总是失败,因为它是在比较实例,而我的盒装值实例总是不同的。
不过,我本以为 removeMessages
的幕后实施如下:
// 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;
}
我的解决办法是做这样的事情:
LongSparseArray<Object> objects = new LongSparseArray<>();
Handler handler = new Handler();
void sendMessageDelayed(int what, long key, long delayMillis)
{
Object object = key;
objects.put(key, object);
Message msg = handler.obtainMessage(what, object);
handler.sendMessageDelayed(msg, delayMillis);
}
void removeMessages(int what, long key)
{
Object object = objects.get(key);
if (object != null) {
handler.removeMessages(what, object);
objects.remove(key);
}
}
sendMessageDelayed(12345, 67890L, 10000);
...
removeMessages(12345, 67890L);
PV
(注意:我正在重写我的问题,因为我的第一个版本不准确)。
给定以下代码:
Handler handler = new Handler();
Message msg = handler.obtainMessage(12345, 67890L);
handler.sendMessageDelayed(message, 10000);
...
handler.removeMessages(12345, 67890L);
问题是消息在我发送 10 秒后仍然触发!
为什么 handler.removeMessages
不删除邮件?
问题是 long 到 Long 对象的自动装箱。
在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: }
第 643 行:
object = {java.lang.Long@4686} "67890"
n.obj = {java.lang.Long@4688} "67890"
所以,在我的例子中,比较总是失败,因为它是在比较实例,而我的盒装值实例总是不同的。
不过,我本以为 removeMessages
的幕后实施如下:
// 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;
}
我的解决办法是做这样的事情:
LongSparseArray<Object> objects = new LongSparseArray<>();
Handler handler = new Handler();
void sendMessageDelayed(int what, long key, long delayMillis)
{
Object object = key;
objects.put(key, object);
Message msg = handler.obtainMessage(what, object);
handler.sendMessageDelayed(msg, delayMillis);
}
void removeMessages(int what, long key)
{
Object object = objects.get(key);
if (object != null) {
handler.removeMessages(what, object);
objects.remove(key);
}
}
sendMessageDelayed(12345, 67890L, 10000);
...
removeMessages(12345, 67890L);
PV