2015-08-21 100 views
9

我有使用postDelayed呼叫活动:这将运行在应用程序启动咖啡和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会)

回答

8

当咖啡等待,它实际上确实需要帐户MessageQueue,但是从你觉得有什么不同的方式。要成为空闲,队列必须为空,的任务要从现在的起超过15毫秒运行。

您可以自己检查代码,特别是方法loopUntil()UiControllerImpl.java和文件QueueInterrogator.java。在后面的文件中,您还可以找到Espresso如何检查MessageQueue(方法determineQueueState())的逻辑。

现在,如何解决你的问题?方法有很多种:

  1. 使用AsyncTask代替Handler,睡在后台线程来执行动作onPostExecute()。这样做是因为Espresso将等待AsyncTask完成,但您可能不喜欢另一个线程的开销。

  2. 睡在你的测试代码中,但你不喜欢那种方法。

  3. 编写您的自定义IdlingResource:这是一个通用的机制,让Espresso知道什么时候空闲,以便它可以运行动作和断言。对于这种方法,你可以:

    • 使用自带的咖啡

    • 呼叫increment()CountingIdlingResource当您发布可运行和decrement()可运行里面的逻辑已经运行

    • 后注册您的IdlingResource在测试设置和取消注册它在拆除

参见:docs and sampleanother sample

+1

我想我可能只是抽出消息推入队列,并注入一些其他实现作为IdlingResource。我将在我的代码中有一个默认实现,它遵循处理程序,在测试代码中有一个是IdlingResource和icnrements/decrements – Matt

0

据我所知,没有等到活动结束方法咖啡。你可以实现你自己的waitForCondition版本,机器人已经有了。这样您只需等待需要的时间,您就可以检测到活动未完成的问题。

你基本上每x毫秒轮询你的情况,类似。

while (!conditionIsMet() && currentTime < timeOut){ 
    sleep(100); 
} 

boolean conditionIsMet() { 
    return "espresso check for if your splash view exists"; 
} 
+0

的问题是,Android提供你没有办法真正窥视消息队列,看看是否有任何正在排队。它必须是在启动时被拦截并取代的东西(我认为这是robotium的做法)。 – Matt

+0

waitForCondition类只是轮询你自己写的条件。至于检查队列的机器人,我不这么认为,我也看到过类似机器人的问题。 – JohanShogun

+0

对于这个用例,您应该能够等待发生的操作,而不是查看消息队列(从测试立场来看这真的更有趣)。 – JohanShogun