我有一个带有两个线程的应用程序 - 主要和数据加载器。当数据加载器完成时,它会将一个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)) - 它们永远不会被传递给主线程中的处理程序回调。
我在这里想念什么?
提前致谢:)
答案 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时,它会抛出一个异常。您可能正在编写必须在不同环境下运行的代码,此解决方案将处理更多案例。