【问题标题】: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,因此它们是按身份进行比较的,因为h1h2 是两个不同的对象,它返回false

    关于为什么runnable2被执行: 这两个 Handler 具有相同的底层 Looper,因此它们具有相同的底层消息队列。在内部发布一个 runnable 会将一条消息与您发布到 Handler 的 Runnable 一起排入队列,并且此 Handler 作为此消息的目标。

    当您调用removeCallbacksAndMessages(null) 时,Handler 请求消息队列删除所有以自身为目标的消息。因此,在您的情况下,队列将有两条消息: 1) 将运行runnable1 和目标h1 的消息 2) 将运行runnable2 和目标h2 的消息

    因此当您调用h2.removeCallbacksAndMessages(null) 时,消息队列只会删除从h2 发布的消息。

    因此,尝试只为主线程设置一个 Handler 是没有意义的 - 事实上,如果您有多个 Runnable 海报,但只想取消其中一些,这可能会适得其反。

    【讨论】:

      猜你喜欢
      • 2013-08-02
      • 1970-01-01
      • 2015-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-03
      相关资源
      最近更新 更多