我目前正在尝试活动测试教程(Found here),并遇到问题。似乎每当我尝试在UIThread中调用某些东西时,我都会得到一个java.lang.NullPointerException。
public void testSpinnerUI() {
mActivity.runOnUiThread( new Runnable() {
public void run() {
mSpinner.requestFocus();
}
});
}
这给了我:
不完整:java.lang.NullPointerException
,没有别的。我现在在两个不同的样品上尝试了这个,结果相同。我试着围绕mSpinner.requestFocus()调用使用try / catch子句,似乎mSpinner在线程内是null。我已经使用在同一个示例中找到的setUp()函数正确设置了它,并且快速assertNotNull(mSpinner)向我显示在setUp()函数之后mSpinner实际上不是null。造成这种情况的原因是什么?
EDIT;好的,已经完成了一些测试。似乎正在测试的应用程序在每个测试之间重置。这基本上使我必须在每次测试之间重新实例化所有变量。这是正常的吗?
答案 0 :(得分:6)
好的,所以看来我现在就开始工作了。至少到某一点。我仍然无法在runOnUiThread()中运行任何东西,但我发现使用@UiThreadTest注释给了我满意的结果。我不再获得NullPointerExceptions,并且setUp()方法甚至可以正确运行。我不知道造成这种情况的原因,但是嘿,至少它正在起作用:)。
答案 1 :(得分:3)
我遇到了同样的问题。使用runOnUiThread()的测试在我的测试类的成员字段上定期与NPE失败。在调试器中,我可以看到在UI线程执行代码时它们是空的。
据我所知,runOnUiThread只是发布一个稍后将被分派的事件。不幸的是,这通常会在主线程中完成测试的其余部分并且我的对象被销毁之后发生。这可能是因为模拟器太忙而无法在测试继续之前处理UIEvent。
我能够通过使用CyclicBarrier来解决这个问题,以确保在UiThread中运行代码之前我的测试没有继续。我创建了一个方法来封装它并在我的测试中使用它而不是Activity.runOnUiThread():
private void myRunOnUiThread( final Runnable r) {
final CyclicBarrier barrier = new CyclicBarrier(2);
mActivity.runOnUiThread(
new Runnable() {
public void run() {
r.run();
try { barrier.await(); } catch (Exception e) { e.printStackTrace(); }
}});
try { barrier.await(); } catch (Exception e) { e.printStackTrace(); }
}
这是我在测试类中的样子:
public void testFieldUI() {
myRunOnUiThread(
new Runnable() {
public void run() {
mRateView.requestFocus();
mRateView.selectAll();
}
}
);
sendKeys(KeyEvent.KEYCODE_DEL); // delete everything
assertTrue("rate is deleted", mRateView.getText().length() == 0);
答案 2 :(得分:1)
不要问我为什么,但是如果你在你的代码中添加至少一个sendKey()就可以了:
public void testSoundSpinnerUI() {
myActivity.runOnUiThread(new Runnable() {
public void run() {
mySoundSpinner.requestFocus();
mySoundSpinner.setSelection(0);
}
});
sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
}
答案 3 :(得分:1)
我遇到了同样的问题以及一些其他奇怪的空指针异常。奇怪的是,这似乎与在测试类中使用静态成员变量有关。
只要我从变量中删除了静态关键字,就会解决所有问题。它没有任何意义,因为变量与首先导致异常的代码行无关。
但现在一切正常......
答案 4 :(得分:1)
我遇到了同样的问题,而且Drew建议问题是Test类在UI-thread完成之前完成并销毁了我的成员变量。这导致UI线程中的空指针异常。
我的修复是我创建了boolean running
变量,它告诉UI线程是否仍在运行。如果UI线程仍在运行,当'main'线程即将完成时,我正在检查running
变量是否为真。如果是的话,我正在睡觉,例如200毫秒再次尝试。在UI线程中,最后一件事是我将runnable
设置为false并且主线程也存在。
public void testSomething() {
activity.runOnUiThread(
new Runnable() {
public void run() {
// Run something on UI-thread
// In the end of this thread, set stillRunning false
stillRunning = false;
}
});
while(stillRunning) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// Handle exception
}
}
}
答案 5 :(得分:0)
此异常主要是由您的活动启动时引发的另一个异常引起的。因为它没有创建活动,你得到NullPointException。尝试通过设置断点来调试测试,第一次调用getActivity()并在代码中找到错误。