gpt4 book ai didi

android - Handlers、MessageQueue、Looper,它们都运行在 UI 线程上吗?

转载 作者:IT王子 更新时间:2023-10-29 00:05:50 24 4
gpt4 key购买 nike

我正试图将我的头脑围绕在线程上,我知道我可以使用 Handler 将消息/runnables 发布到 MessageQueue,而 MessageQueueLooper 拾取并发送回 Handler 进行处理。

如果我在我的 Activity 中发布到 Handler,是 ActivityHandlerMessageQueueLooper全部运行在UI线程上?如果没有,有人可以解释一下这一切是如何结合在一起的吗? :)

最佳答案

简答:它们都在同一个线程上运行。如果从 Activity 生命周期回调实例化,它们都在主 UI 线程上运行。

长答案:

一个线程可能有一个Looper,其中包含一个MessageQueue为了使用这个工具,你必须创建一个Looper 在当前线程上通过调用(静态)Looper.prepare(),然后通过调用(也是静态)Looper.loop() 开始循环。这些是静态的,因为每个线程只应该有一个 Looper

loop() 的调用通常在一段时间内不会返回,但会继续接收消息(“任务”、“命令”或您喜欢的任何名称) ) 从 MessageQueue 中取出并单独处理它们(例如,通过回调消息中包含的 Runnable )。当队列中没有消息时,线程会阻塞,直到有新消息。要停止 Looper,您必须在其上调用 quit()(这可能不会立即停止循环,而是设置一个私有(private)标志,从循环,发出信号停止)。

但是,您不能直接将消息添加到队列中。相反,您注册一个 MessageQueue.IdleHandler 来等待一个 queueIdle() 回调,您可以在其中决定是否要执行某些操作。依次调用所有处理程序。 (所以 “队列”并不是真正的队列,而是定期调用的回调集合。)

关于上一段的注意事项:我实际上猜到了。我找不到任何关于此的文档,但这是有道理的。

更新:ahcox' commenthis answer .

因为工作量很大,框架提供了Handler类来简化事情。当您创建 Handler 实例时,它(默认情况下)绑定(bind)到已附加到当前线程的 Looper。 (Handler 知道要附加到哪个 Looper,因为我们之前调用了 prepare(),它可能存储了对 Looper< 的引用ThreadLocal 中。)

使用 Handler,您只需调用 post() 即可“将消息放入线程的消息队列”(可以这么说)。 Handler 将处理所有 IdleHandler 回调内容,并确保您发布的 Runnable 被执行。 (如果您延迟发布,它也可能会检查时间是否正确。)

明确一点:真正使循环线程某事的唯一方法是向其循环发布消息。这在您调用 looper 上的 quit() 之前有效。


关于 android UI 线程: 在某些时候(可能在创建任何 Activity 等之前)框架已经设置了一个 Looper(包含一个 MessageQueue) 并启动它。从这一点开始,UI 线程上发生的一切都通过该循环。这包括 Activity 生命周期管理等。您覆盖的所有回调(onCreate()onDestroy()...)至少是从该循环间接调度的。例如,您可以在异常的堆栈跟踪中看到这一点。 (你可以试试,在onCreate()的某处写int a = 1/0;...)


我希望这是有道理的。抱歉之前不清楚。

关于android - Handlers、MessageQueue、Looper,它们都运行在 UI 线程上吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5193913/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com