Espresso 和 postDelayed
Espresso and postDelayed
我有一个 activity 正在使用 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,这看起来很老套(就像 Thread.sleep 那样)
据我所知,没有等待 activity 完成浓缩咖啡的方法。你可以实现你自己的 waitForCondition 版本,这是 robotium 拥有的。这样您就可以只等待需要的时间,并且可以检测到 activity 未完成的问题。
您基本上每隔 x 毫秒就轮询一次您的状况,例如。
while (!conditionIsMet() && currentTime < timeOut){
sleep(100);
}
boolean conditionIsMet() {
return "espresso check for if your splash view exists";
}
当 Espresso 等待时,它确实会考虑 MessageQueue
,但与您想象的方式不同。要空闲,队列必须为空,或 有任务运行超过15从现在开始的毫秒数.
大家可以自行查看代码,尤其是UiControllerImpl.java
中的方法loopUntil()
和文件QueueInterrogator.java
。在后一个文件中,您还将找到 Espresso 如何检查 MessageQueue
(方法 determineQueueState()
)的逻辑。
现在,如何解决你的问题?有很多方法:
使用 AsyncTask
而不是 Handler
,在后台线程休眠并执行操作 onPostExecute()
。这样做是因为 Espresso 会等待 AsyncTask
完成,但您可能不喜欢另一个线程的开销。
睡在你的测试代码中,但你已经不喜欢这种方法了。
编写您的自定义 IdlingResource
:这是一种让 Espresso 知道什么时候空闲的通用机制,以便它可以 运行 操作和断言。对于这种方法,您可以:
使用 Espresso 自带的 class CountingIdlingResource
当你 post 你的 运行nable 和 decrement()
在你的逻辑 运行nable 里面调用 increment()
72=]
在测试设置中注册您的 IdlingResource
并在拆卸中取消注册
另请参阅:docs and sample,
我有一个 activity 正在使用 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,这看起来很老套(就像 Thread.sleep 那样)
据我所知,没有等待 activity 完成浓缩咖啡的方法。你可以实现你自己的 waitForCondition 版本,这是 robotium 拥有的。这样您就可以只等待需要的时间,并且可以检测到 activity 未完成的问题。
您基本上每隔 x 毫秒就轮询一次您的状况,例如。
while (!conditionIsMet() && currentTime < timeOut){
sleep(100);
}
boolean conditionIsMet() {
return "espresso check for if your splash view exists";
}
当 Espresso 等待时,它确实会考虑 MessageQueue
,但与您想象的方式不同。要空闲,队列必须为空,或 有任务运行超过15从现在开始的毫秒数.
大家可以自行查看代码,尤其是UiControllerImpl.java
中的方法loopUntil()
和文件QueueInterrogator.java
。在后一个文件中,您还将找到 Espresso 如何检查 MessageQueue
(方法 determineQueueState()
)的逻辑。
现在,如何解决你的问题?有很多方法:
使用
AsyncTask
而不是Handler
,在后台线程休眠并执行操作onPostExecute()
。这样做是因为 Espresso 会等待AsyncTask
完成,但您可能不喜欢另一个线程的开销。睡在你的测试代码中,但你已经不喜欢这种方法了。
编写您的自定义
IdlingResource
:这是一种让 Espresso 知道什么时候空闲的通用机制,以便它可以 运行 操作和断言。对于这种方法,您可以:使用 Espresso 自带的 class
CountingIdlingResource
当你 post 你的 运行nable 和
decrement()
在你的逻辑 运行nable 里面调用increment()
72=]在测试设置中注册您的
IdlingResource
并在拆卸中取消注册
另请参阅:docs and sample,