如何从另一个线程获取主线程的消息队列? Looper.getMainLooper()获取主线程的活套,但我无法找到一种方法来获取另一个线程活套的MessageQueue。而且,我如何获得主要活套的处理程序?我无法找到任何方法来获取它。获取主线程的消息队列和处理程序
回答
当你得到主线程循环之后,你应该能够调用myQueue来获得主线程MessageQueue。
http://developer.android.com/reference/android/os/Looper.html#myQueue%28%29
该文档说它返回当前线程的MessageQueue,我想在与主线程不同的线程上获取它。 –
对不起,我误解了这个问题。 MessageQueue是一个内部结构,我不确定Android是否允许您直接从线程之外访问它。一旦你得到它,你想用MessageQueue做什么,而不能使用主线程的处理程序和循环工具来完成呢? – RAnderson
我想添加一个idleHandler来检查主线程是否没有做任何事情。顺便说一下,我还需要主线程的处理程序 - 我为此编辑了我的问题。 –
@ r.v,
我也有类似的需求。我想知道什么时候MessageQueue是空的,什么时候我发布了一些东西,我想知道它什么时候变空了,什么也没做。我看着MessageQueue.IdleHandler
,发现它不像我想的那样表现出我想出了另一种解决方案。
在我的情况下,我想使用Looper/Handler机制来顺序执行文件下载。基本上我想执行的每个下载都包装在一个Runnable中。我一次只需要一个运行,所以这种模式运行良好,无需深入研究更多涉及线程解决方案的细节。另外,我想知道什么时候我首先将某些东西放入队列中并开始工作,并想知道它何时完成(队列为空)。
我能够使用处理程序的消息机制来实现此目的。消息按照Runnables顺序处理,因此您可以策略性地将消息放入队列中,以帮助您了解队列的状况。与处理程序队列中的Runnables不同,对于最终提供解决方案的消息,有一些查询和删除功能。
我每添加一个可运行的处理程序(通过Handler.post
)时间我要做的就是,我也删除自定义QUEUE_EMPTY
消息的所有实例,然后添加一个新的QUEUE_EMPTY
消息。这可以确保我在队列末尾有一个QUEUE_EMPTY
消息。一旦我在我的子类Handler中遇到QUEUE_EMPTY
消息,我知道我在队列的末尾。另外,如果我在添加可运行的程序时在队列中找不到QUEUE_EMPTY
消息,我知道队列是空的,线程空闲。
正如有些人会很快指出的那样,这种解决方案存在一些真正的低效率问题。如果队列中有大量条目,则必须遍历队列中的这些“标记”消息可能是一个真正的性能问题。就我而言,我一次只处理少量文件下载,所以任何性能损失都可以忽略不计。如果你有类似的情况,我认为这是一个非常合理的解决方案。对于Android SDK来说,将这些基本功能提供给MessageQueue
会很好。理想情况下,我不同意MessageQueue,但知道它何时处于空闲/工作/空闲状态似乎是合理的事情,而且我知道有很多情景需要知道这些事情。
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!");
}
}
}
};
使用Handler类与Looper的消息队列进行交互。
要与主要线程的消息队列进行交互,
Handler mainHandler = new Handler(Looper.getMainLooper(), new Callback() {
@Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
return false;
}
});
mainHandler.post(...);
mainHandler.sendMessage(...);
mainHandler.removeMessage(...);
现在,您可以发送,删除和接收消息。
- 1. 消息队列多线程
- 2. 每个线程或每个处理程序的Android消息队列
- 3. JMS队列上多线程消息处理的最佳实践
- 4. 处理程序未能向主线程传递消息或Runnable
- 5. 线程/多处理/队列?
- 6. 有序多线程消息处理
- 7. 发送消息与处理程序没有队列或延迟
- 8. Android UI线程和消息处理程序混淆
- 9. 发送消息给处于死线程的处理程序
- 10. 消息处理程序
- 11. SOAP消息处理程序
- 12. UIScrollView消息处理程序
- 13. 消息队列,C++多线程
- 14. 消息队列VS线程池
- 15. 如何获取jms队列中待处理消息的数量
- 16. Java队列中的多线程处理
- 17. 将消息发送到死线程上的处理程序
- 18. 与线程,处理程序和信息处理:“重新启动”线程
- 19. DLL中的Windows消息队列处理
- 20. 多线程批处理队列
- 21. 如何多线程队列处理
- 22. iOS GCD:主线程从主队列以外的队列中取出队列?
- 23. 线程休眠处理JMS消息时
- 24. Anynchronous多线程消息处理
- 25. Clojure消息处理/异步,多线程
- 26. 消息队列应用程序
- 27. 获取主队列未在主线程执行
- 28. Android线程处理程序未收到消息
- 29. 使用处理IO队列的线程来提升线程池
- 30. 队列阻塞主线程
为什么?你不需要直接混淆队列。 – CommonsWare
我只是想添加一个idleHandler来检查主线程是否在做某事 –
@CommonsWare我不知何故想检查主线程的messagequeue是否为空。我是这些概念的新手,并且正在考虑使用idleHandler在队列变空时得到通知。 –