处理程序无法向主线程传递消息或Runnable

时间:2010-02-18 15:28:42

标签: android user-interface multithreading

我有一个带有两个线程的应用程序 - 主要和数据加载器。当数据加载器完成时,它会将一个Runnable对象发布到主线程(如DevGuide中所述),但它永远不会被传递和运行。

以下是基本代码:

class MyApp extends Application
{
   public void onCreate()
   {
         LoaderThread t = new LoaderThread();
         t.start();
   }

   private class LoaderThread extends Thread
   {
        public void run()
        {
             SystemClock.sleep(2000);
             boolean res = m_handler.post(m_runnable);
             if(res)
                Log.d(TAG, "Posted Runnable");
        }
   }

   private final Handler m_handler = new Handler();
   private final Runnable m_runnable = new Runnable() {
             public void run()
             {
                 Log.d(TAG, "Hey, i'm runnable!");
             }
        }
}

同样重要的是要注意我将此代码作为派生自ApplicationTestCase的单元测试运行:

class MyAppTest : public ApplicationTestCase
{
     public MyAppTest()
     {
          super(MyApp.class);
     }

     public void testLoading()
     {
          createApplication();
          // few asserts follow here...
     }
}

所以这失败了。 Runnable永远不会被调用run(),尽管日志表明它已成功发布。 我也尝试发送简单的消息而不是发布runnable(例如m_handler.sendEmptyMessage(1)) - 它们永远不会被传递给主线程中的处理程序回调。

我在这里想念什么?

提前致谢:)

3 个答案:

答案 0 :(得分:1)

Handler需要Looper才能运作。 Looper提供Handler所需的邮件队列。

Activity的所有实例都有Looper,其中一个用于处理UI事件,但您可以在其他位置创建Looper的实例。

查看您的日志输出,看看Android是否抱怨缺少Looper

如果是,您可以通过在onCreate()方法的顶部添加以下内容来解决问题:

Looper.prepare(); 
m_handler = new Handler();
Looper.run();

并从代码中删除m_handler的初始化。

答案 1 :(得分:0)

Handler仅适用于Activity AFAIK。您正试图在Application

中使用它

答案 2 :(得分:0)

调用Looper.prepare()的替代方法是致电new Handler(Looper.getMainLooper())。调用Looper.prepare()的问题是,当你的线程上已经有一个looper时,它会抛出一个异常。您可能正在编写必须在不同环境下运行的代码,此解决方案将处理更多案例。

请参阅: AsyncTask and Looper.prepare() error

相关问题