android - 获取主线程的消息队列和处理程序

标签 android message-queue handler looper

如何从另一个线程获取主线程的消息队列? Looper.getMainLooper() 获取主线程的循环器,但我无法找到一种方法来获取另一个线程的循环器的 MessageQueue。此外,如何获得主循环程序的处理程序?我找不到任何方法来获取它。

最佳答案

@r.v,

我也有类似的需求。我想知道 MessageQueue 什么时候是空的,什么时候我发布一些东西让它做,我想知道什么时候它变空了,没有什么可做的。我查看了 MessageQueue.IdleHandler,发现它的行为与我想的不一样,我想出了另一个解决方案。

在我的例子中,我想使用 Looper/Handler 机制来顺序执行文件下载。基本上我要执行的每个下载都包含在一个 Runnable 中。我一次只希望运行一个,因此这种模式运行良好,而无需深入研究更复杂的线程解决方案的具体细节。此外,我想知道什么时候我第一次将某些东西放入队列并开始工作,并想知道它何时完全完成(队列为空)。

我能够使用处理程序的消息机制来实现这一点。消息按顺序与 Runnable 一起处理,因此您可以有策略地将消息放入队列中,以帮助您了解队列的情况。与 Handler 队列中的 Runnable 不同,消息具有一些查询和删除功能,最终提供解决方案。

我所做的是每次向处理程序添加一个可运行对象(通过 Handler.post),我还删除自定义 QUEUE_EMPTY 消息的所有实例,然后添加一条新的 QUEUE_EMPTY 消息。这确保我在队列末尾有一个 QUEUE_EMPTY 消息。一旦我在我的子类处理程序中遇到 QUEUE_EMPTY 消息,我就知道我在队列的末尾。此外,如果我在添加可运行对象时未在队列中找到 QUEUE_EMPTY 消息,我就知道队列为空且线程空闲。

正如一些人很快会指出的那样,此解决方案确实存在一些效率低下的问题。如果队列中有大量条目,则必须为这些“标记”消息遍历队列可能是一个真正的性能问题。就我而言,我一次只处理少量文件下载,因此任何性能损失都可以忽略不计。如果你有类似的情况,我认为这是一个非常合理的解决方案。如果 Android SDK 能够为 MessageQueue 提供这些基本功能,那就太好了。我同意理想情况下您不想弄乱 MessageQueue,但知道它何时空闲/工作/空似乎是合理的事情,而且我确信在很多情况下了解这些事情是有值(value)的。

    class DownloaderThread extends Thread
{
    private static final int QUEUE_EMPTY = 9999;
    private MyHandler handler;

    @Override
    public void run()
    {
        try
        {
            Looper.prepare();
            handler = new MyHandler();
            Looper.loop();
        }
        catch (Throwable t)
        {
            Log.e(TAG, "halted due to an error", t);
        }
    }

    public void post(Runnable r)
    {
        if(!handler.hasMessages(QUEUE_EMPTY))
        {
            Log.v(TAG, "Download queue was empty.  First element being added.");
        }

        handler.post(r);
        handler.removeMessages(QUEUE_EMPTY);
        handler.sendEmptyMessage(QUEUE_EMPTY);
    }

    class MyHandler extends Handler
    {
        @Override
        public void handleMessage(Message msg)
        {
            if(msg.what == QUEUE_EMPTY)
            {
                Log.v(TAG, "Download runnable queue is empty!");
            }
        }
    }
};

关于android - 获取主线程的消息队列和处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6558786/

相关文章:

android - 谷歌云翻译 api 库未构建 - 发现重复类

java - 单击按钮时在后台通过电子邮件发送文本文件

PHP + MySQL 队列

android - post(Runnable r) 到主线程的处理程序和在主线程中运行有什么区别

android - handler.postDelayed 与 ScheduledThreadPoolExecutor.scheduleWithFixedDelay

android - 尝试从命令行执行脚本时出现 Python 语法错误

android - 如何在没有我的应用程序的情况下阻止 Eddystone 将内容推送到手机

python - 用 python 编写的 AMQP 代理?

python - 排队: N producers to N consumers

jquery - jquery 中的一键多次点击处理程序