2010-02-18 66 views
4

我有一个带有两个线程(主线程和数据加载程序)的应用程序。当数据加载器完成后,它将一个Runnable对象发布到主线程(如DevGuide中所述),但它永远不会交付和运行。处理程序未能向主线程传递消息或Runnable

这里的基本代码:

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永远不会运行()。 我也尝试发送简单的消息,而不是发布runnable(例如,m_handler.sendEmptyMessage(1)) - 它们从未在主线程中传递到处理程序的回调函数。

我在这里错过了什么?

感谢提前:)

回答

1

A Handler需要Looper才能工作。 Looper提供了Handler所需的消息队列。

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

看看你的日志输出,看看Android是否抱怨没有Looper

如果是,你也许可以修复由以下内容添加到您的onCreate()方法的顶部:

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

而从后面的代码去除m_handler初始化。

+0

我认为是这样,但Looper确实创建。因为当我尝试自己创建它(包括尝试上面的建议)时,我得到: “java.lang.RuntimeException:每个线程只能创建一个Looper” 另外我刚刚发现代码(不变)很好,当在一个完整的应用程序在操作系统内运行。另一方面,当我将它作为测试用例运行时,它无法工作... 任何提示? Looper是好的,它不是空的,没有例外,日志中没有错误。我很困惑。 – dimsuz 2010-02-18 16:46:12

+0

感谢您的提示!我的代码不在一个活动内,因此不在循环内... 我想知道为什么通过处理程序发送的消息只在调用线程停止时才会发送。 – Sney 2011-06-22 06:08:16

0

Handler只能在一个Activity AFAIK。您正试图在Application中使用它。

+0

我刚刚发现,作为一个测试运行时,当作为OS的应用程序中运行这个非常的代码工作,但失败......所以我想这是别的东西丢失。也许与活动有关...... – dimsuz 2010-02-18 16:40:54

0

拨打Looper.prepare()的另一种方法是致电new Handler(Looper.getMainLooper())。调用Looper.prepare()时遇到的问题是,当线程中已经存在循环时,它会抛出异常。有可能你正在编写必须在不同环境下运行的代码,并且此解决方案将处理更多的案例。

参见: AsyncTask and Looper.prepare() error