我有一个使用postDelayed调用的活动:
public class SplashActivity extends Activity {
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(...);
handler.postDelayed(new Runnable() {
public void run() { finish(); }
}, 3000L);
}
}
这在应用程序启动时运行,我需要导航它和我的登录屏幕。然而,UIController的loopMainThreadUntilIdle似乎没有考虑处理程序中的底层MessageQueue。因此,当队列中仍有消息时,此操作立即完成。
onView(withId(R.id.splash_screen)).perform(new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isAssignableFrom(View.class);
}
@Override
public String getDescription() {
return "";
}
@Override
public void perform(final UiController uiController, final View view) {
uiController.loopMainThreadUntilIdle();
}
});
我一直不知道如何阻塞直到队列耗尽。Android本身是阻止我做很多事情,我想尝试(如扩展Handler和覆盖postDelayed方法,等等…)
谁对如何处理postDelayed有什么建议?我宁愿避免uiController。loopMainThreadForAtLeast,它看起来像一个线程。
当Espresso等待时,它实际上会考虑MessageQueue
,但方式与你想象的不同。要空闲,队列必须为空,或从现在开始有超过15毫秒的任务要运行。
您可以自己检查代码,特别是UiControllerImpl.java
中的loopUntil()
方法和QueueInterrogator.java
文件。在后一个文件中,您还可以找到Espresso如何检查MessageQueue
(方法determineQueueState()
)的逻辑。
现在,如何解决你的问题?有很多方法:
-
使用
AsyncTask
代替Handler
,在后台线程上休眠并执行onPostExecute()
操作。因为Espresso将等待AsyncTask
完成,但是您可能不喜欢另一个线程的开销。 -
在你的测试代码中睡觉,但是你已经不喜欢这种方法了
-
写你的自定义
IdlingResource
:这是一个通用的机制,让Espresso知道什么是空闲的,这样它就可以运行动作和断言。对于这种方法,您可以:-
使用Espresso自带的
CountingIdlingResource
类 -
调用
increment()
当你张贴你的runnable和decrement()
内运行后,你的逻辑已经运行 -
在测试设置中注册
IdlingResource
并在拆除中取消注册
-
参见:docs和sample,另一个示例
据我所知,在浓缩咖啡中没有等待活动完成方法。你可以实现你自己版本的waitForCondition,这是robotium所拥有的。这样,你只需要等待所需的时间,你可以检测到你的活动未完成的问题。
你基本上每隔x毫秒轮询一次你的状况,就像。
while (!conditionIsMet() && currentTime < timeOut){
sleep(100);
}
boolean conditionIsMet() {
return "espresso check for if your splash view exists";
}