【问题标题】:robolectric: Handler.postDelayed is run immediatelyrobolectric:Handler.postDelayed 立即运行
【发布时间】:2015-01-23 00:53:52
【问题描述】:

我正在使用 Robolectric 3.0 (ToT)。

onCreate 的活动中,我拨打了以下电话:

mHandler.postDelayed(mRunnable, 10 * 60 * 1000)

然后在我的 Robolectric 测试用例中,我设置了活动,并且可运行对象立即启动(碰巧它调用 finish())。我怎样才能防止这种情况发生?

我使用了ShadowLooper.pauseMainLooper();,它可以防止触发Runnable,但这对我来说不是一个好的解决方案。我在测试中发送广播,当主循环暂停时,他们没有收到。当我取消暂停时,意图都被传递到广播接收器并且Runnable 运行。如何让广播接收器运行,而不是 延迟 Runnable.

【问题讨论】:

  • 我能够用robolectric 2.4 重现同样的问题。我会在 Robolectric 问题跟踪器上创建票证(我看到你已经这样做了)并让他们了解问题。可能如预期。作为解决方法,我将创建和代理类来安排延迟事件并在测试中模拟它。编写额外的功能来通过测试并不好,但它应该可以工作
  • 这个问题似乎出在Android自己的调度器中;我发现 Handler.postDelayed(foo, 1000) 在大约 200 毫秒后触发,至少在 Android 4.2 上是这样。

标签: android testing handler robolectric


【解决方案1】:

我没有太多将 Runnables 发布到 Handler 或使用 Looper 的经验。如果我是你,我会使用 Handler Messages 来请求执行某个操作。您可以使用Handler.SendMessageDelayed(message,time) 来延迟任务的发生,使用Handler.SendMessage(message) 来执行即时任务。您需要在 Handler 的 handleMessage 函数中运行您的任务。有关示例,请参见代码。

public class incomingHandler extends Handler {
   @Override
   public synchronized void handleMessage(Message msg){
   switch(msg.what){
case 0 : finish(); break;
case 1 : "RUN FUNCTION OR DO SOMETHING ELSE"; break;
default : "HAVE YOUR DEFAULT MESSAGE SERVICE HERE";}
@Override
protected void onCreate(Bundle savedInstanceState) 

{super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_ui);
    Handler mHandler = new incomingHandler();
    mHandler.sendMessage(Message.obtain(null, 1)); 
//This will cause your function to run immediately

    mHandler.sendMessageDelayed(Message.obtain(null,0),5000L) ;
//This will cause you activity to finish after 5 seconds
}

我希望这会有所帮助。

【讨论】:

  • 这没用,发送消息也会立即发送。
  • 你还在叫looper吗?
  • 这个问题恐怕我没听懂。
  • 正在调用这个命令 Looper.getMainLooper().loop();或在您的代码中的任何地方类似的东西?
  • 这段代码对我有用。我不明白为什么你的消息没有延迟。对不起,伙计。祝你好运。如果您发布部分代码,其他人也许可以帮助您。
【解决方案2】:

深入研究 roboletics 我看到 roboletics 会立即运行未来的任务(你为什么问?我猜他们不希望你等待任务)但会更新一个名为 currentTime 的变量(Scheduler.类)到新的假时间。

所以你几乎不用等待任务。

而且似乎还有一个设计缺陷,因为没有等待,它们实际上并没有正常运行任务。 例如,如果您将在 onLooperPrepared() 中调用 handler.sendEmptyMessage(),任务将立即发出,不会排队或等待 结束onLooperPrepared() 调用。

目前我已经尝试自己模拟 Looper,并且取得了一些成功。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-17
    • 2020-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多