如何从另一个线程获取主线程的消息队列? 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/