【问题标题】:several Handlers for the UI ThreadUI 线程的几个处理程序
【发布时间】:2020-10-09 11:03:31
【问题描述】:
根据documentation:
特定线程的所有 Handler 对象都接收相同的
消息。
但是在这段代码中:
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 作为主线程?
【问题讨论】:
标签:
android
android-handler
android-looper
【解决方案1】:
所以,对于h1.equals(h2) 返回false,解释非常简单——Handler 类不会覆盖equals,因此它们是按身份进行比较的,因为h1 和h2 是两个不同的对象,它返回false。
关于为什么runnable2被执行:
这两个 Handler 具有相同的底层 Looper,因此它们具有相同的底层消息队列。在内部发布一个 runnable 会将一条消息与您发布到 Handler 的 Runnable 一起排入队列,并且此 Handler 作为此消息的目标。
当您调用removeCallbacksAndMessages(null) 时,Handler 请求消息队列删除所有以自身为目标的消息。因此,在您的情况下,队列将有两条消息:
1) 将运行runnable1 和目标h1 的消息
2) 将运行runnable2 和目标h2 的消息
因此当您调用h2.removeCallbacksAndMessages(null) 时,消息队列只会删除从h2 发布的消息。
因此,尝试只为主线程设置一个 Handler 是没有意义的 - 事实上,如果您有多个 Runnable 海报,但只想取消其中一些,这可能会适得其反。