2011-07-02 83 views
4

如何从另一个线程获取主线程的消息队列? Looper.getMainLooper()获取主线程的活套,但我无法找到一种方法来获取另一个线程活套的MessageQueue。而且,我如何获得主要活套的处理程序?我无法找到任何方法来获取它。获取主线程的消息队列和处理程序

+0

为什么?你不需要直接混淆队列。 – CommonsWare

+0

我只是想添加一个idleHandler来检查主线程是否在做某事 –

+0

@CommonsWare我不知何故想检查主线程的messagequeue是否为空。我是这些概念的新手,并且正在考虑使用idleHandler在队列变空时得到通知。 –

回答

0

当你得到主线程循环之后,你应该能够调用myQueue来获得主线程MessageQueue。

http://developer.android.com/reference/android/os/Looper.html#myQueue%28%29

+0

该文档说它返回当前线程的MessageQueue,我想在与主线程不同的线程上获取它。 –

+0

对不起,我误解了这个问题。 MessageQueue是一个内部结构,我不确定Android是否允许您直接从线程之外访问它。一旦你得到它,你想用MessageQueue做什么,而不能使用主线程的处理程序和循环工具来完成呢? – RAnderson

+0

我想添加一个idleHandler来检查主线程是否没有做任何事情。顺便说一下,我还需要主线程的处理程序 - 我为此编辑了我的问题。 –

3

@ 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!"); 
      } 
     } 
    } 
}; 
1

使用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(...); 

现在,您可以发送,删除和接收消息。