- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正试图将我的头脑围绕在线程上,我知道我可以使用 Handler
将消息/runnables 发布到 MessageQueue
,而 MessageQueue
由 Looper
拾取并发送回 Handler
进行处理。
如果我在我的 Activity 中发布到 Handler
,是 Activity
、Handler
、MessageQueue
和 Looper
全部运行在UI线程上?如果没有,有人可以解释一下这一切是如何结合在一起的吗? :)
最佳答案
简答:它们都在同一个线程上运行。如果从 Activity
生命周期回调实例化,它们都在主 UI 线程上运行。
长答案:
一个线程可能有一个Looper
,其中包含一个MessageQueue
。为了使用这个工具,你必须创建一个Looper
在当前线程上通过调用(静态)Looper.prepare()
,然后通过调用(也是静态)Looper.loop() 开始循环
。这些是静态的,因为每个线程只应该有一个 Looper
。
对 loop()
的调用通常在一段时间内不会返回,但会继续接收消息(“任务”、“命令”或您喜欢的任何名称) ) 从 MessageQueue
中取出并单独处理它们(例如,通过回调消息中包含的 Runnable
)。当队列中没有消息时,线程会阻塞,直到有新消息。要停止 Looper
,您必须在其上调用 quit()
(这可能不会立即停止循环,而是设置一个私有(private)标志,从循环,发出信号停止)。
但是,您不能直接将消息添加到队列中。相反,您注册一个
MessageQueue.IdleHandler
来等待一个
queueIdle()
回调,您可以在其中决定是否要执行某些操作。依次调用所有处理程序。 (所以
“队列”并不是真正的队列,而是定期调用的回调集合。)
关于上一段的注意事项:我实际上猜到了。我找不到任何关于此的文档,但这是有道理的。
更新:见ahcox' comment和 his 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/
我在其他帖子上看到过这个错误,但不是针对这种情况。 我有两个类使用 MessageQueue 做同样的事情。因此,我将队列的创建和处理抽象为一个辅助类。我遇到了这个错误,而且我看不出如何多次处理队列。
我还有两个问题。1. 如何将消息队列名称作为命令行参数传递?例如我写道: char src[50] , dest[50]; strcpy(src , "/"); strcpy(dest , argv[
据我了解,如果 MessageQueue 中只有带有 future 时间戳的消息,则 MessageQueue 会阻塞 Looper 的循环直到那个时间到来。但如果 MessageQueue 完全为空
我一直在浏览有关消息队列的文档,但似乎找不到我正在寻找的信息。我想要完成的任务是在每次调用 MySQL 数据库过程时记录该过程的名称,以便跟踪每个过程的调用频率。我的想法是在调用时将名称记录到 Mes
我一直在查看处理来自 MSMQ 的消息的服务的示例代码。在代码中,在 ReceiveCompletedEventHandler 的开头立即调用 EndReceive() 方法,然后它开始实际处理消息的
我只想在异步方法中接收我的消息!它卡住了我的用户界面 public async void ProcessMessages() { MessageQueue MyMess
我目前有一个后台线程。在这个线程中是一个无限循环。 这个循环偶尔更新数据库中的一些值,然后在 MessageQueue 上监听 1 秒(使用 queue.Receive(TimeSpan.FromSe
我用 C# 编写的应用程序使用 .NET 中的 MessageQueue 类与另一个远程应用程序进行消息通信,MessageQueue 应始终与远程 messageQueue 在所有情况下“连接”(存
我想先将一个类添加到 MessageQueue 的 MessageContent,然后再将其添加到 QueueStorage。 示例 class udpates { public int us
我正在调试 Android 框架,Handler 处理消息的速度很慢,所以我也许应该检查 Handler 的 MessageQueue 以查看消息是否具有低优先级或队列太长。 我查看了 Handler
我在使用基本的 Microsoft Message Queue 实现时遇到以下问题: 在读取端,消息的 Formatter 属性始终为 null,无论我在发送端输入什么。 发送代码: System.M
我发布这个问题是因为我想知道我对基础知识的想法是否正确。 应该清楚的是,UI-Thread 包含一个 MessageQueue,它与一个 Looper 相关联,以从队列中获取消息/可运行对象以进行处理
我已取消选择在专用队列上发送消息的权限,但 MessageQueue.CanWrite 从未返回 false。我可以切换接收消息权限,并且 CanRead 属性会按预期响应。为什么 CanWrite
我想在 MSMQ 消息队列上使用 Linq。据我所知,我需要将消息队列转换为 IEnumerable Howerver var queryableQ = new MessageQueue(myQueu
我正在使用 PeekCompleted 从 MessageQueue 中读取消息,我在这里执行我的过程,如果一切正常,我需要将其从队列中删除!目前我正在使用 MyMessageQueue.Receiv
我使用以下代码发送消息: var transaction = new MessageQueueTransaction()) transaction.Begin( ); var message = n
这个问题在这里已经有了答案: 关闭 13 年前。 Possible Duplicate: Java and MSMQ 我有一个由另一个组编写的 windows/C# 进程,它将 xml 格式的消息泵
我正在使用 Philip Semanchunk 的 posix_ipc python 模块从 posix 消息队列中读取数据。我编写的 C++ 程序使用包含数据的结构填充队列。我的 python 程序
我目前遇到丢失消息的问题。此错误很少发生,但经常发生,足以令人厌烦。以下是问题的背景: 我已经在 goldmine_service_queue 上打开了消息日志,它是 Windows 2003 服务器
我如何判断一个远程消息队列exists ?文档指出“存在”方法不适用于远程机器。 以下无效(我知道队列路径是准确的,因为我能够将消息发送到队列): if (!MessageQueue.Exists(@
我是一名优秀的程序员,十分优秀!