根据文档:
特定线程的所有处理程序对象都收到相同的 消息。
但是在此代码中:
Handler h1 = new Handler(Looper.getMainLooper());
Handler h2 = new Handler(Looper.getMainLooper());
h1.post(runnable1);
h2.post(runnable2);
h1.removeCallbacksAndMessages(null);
runnable2
被执行,尽管所有回调都被删除了h1
。
此外,h1.equals(h2)
返回false
。
应用程序是否应该只对主线程使用一个Handler
?
因此,对于返回false
h1.equals(h2)
解释非常简单 -Handler
类不会覆盖equals
,因此它们通过标识进行比较,并且由于h1
和h2
是两个不同的对象,因此它返回false
。
关于为什么runnable2
被执行: 这两个处理程序具有相同的基础 Looper,因此它们具有相同的基础消息队列。在内部发布可运行项会将消息与发布到处理程序的 Runnable 一起排队,并将此处理程序作为此消息的目标。
调用removeCallbacksAndMessages(null)
时,Handler
请求消息队列删除所有以自身为目标的消息。因此,在您的情况下,队列将有两条消息: 1( 将运行runnable1
和目标h1
的消息 2( 将运行runnable2
和目标h2
的消息
因此,当您调用h2.removeCallbacksAndMessages(null)
时,消息队列只会删除从h2
发布的消息。
正因为如此,尝试只有一个 Handler 作为主线程是没有意义的 - 事实上,如果您有多个Runnable
海报,但只想取消其中一些,这可能会适得其反。