Handler postDelayed and Thread.sleep()

6
我在代码中使用了 thread.sleep 和 handler postDelayed :
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        Log.e(TAG, "I ran");
        mIsDisconnect = false;
    }
}, DISCONNECT_DELAY);

在处理程序代码之后,当用户按下按钮后,我有以下内容:
while (mIsDisconnect) {
    try {
        Thread.sleep(DELAY);
    } catch (InterruptedException e) {
        Log.e(TAG, "problem sleeping");
    }
}

如果用户等待足够长的时间,我就能在日志中看到"I ran"。但是如果用户在延迟时间结束之前按下按钮,似乎postDelayed永远没有机会执行。我的问题是,thread.sleep()是否会影响handler postDelayed?
编辑:这段代码的目的是只有在DISCONNECT_DELAY秒已经过去后,我才想要程序继续运行。因此如果用户点击得太早,我必须等待经过的时间才能完成。

1
简单来说,Thread.sleep 会阻塞其他进程,而 postDelayed 则不会。 - Saahithyan Vigneswaran
3个回答

12

我假设你的handler与另一个循环在同一线程上运行。(Handler与创建它的线程相关联。)

postDelayed()Runnable放入处理程序线程的消息队列中。当控制返回到线程的Looper时,将处理消息队列。

Thread.sleep()仅会阻塞线程。控制不会返回到Looper,也不能处理消息。在UI线程中休眠几乎总是错误的。

为了实现您想要做的事情,请删除睡眠并简单地使用postDelayed()来发布更改应用程序状态的Runnable (例如,通过设置成员变量mIsDisconnect)。然后,在onClick()中只需检查应用程序状态(mIsDisconnect标志),以确定是否可以继续进行操作。


1
我猜第二个部分在主线程上运行,你没有在线程之间切换。 你不能让主线程睡眠,这会停止所有UI问题和其他应该在此线程(主线程)上运行的事情。 相反,使用处理程序的postDelayed

我正在使用postDelayed。对我尝试做的事情进行了额外的解释。 - Jace
1
我明白了。如果你让线程休眠,第一部分就不会发生。再次强调,避免使用'Thread.sleep()'。 尝试阅读http://developer.android.com/reference/android/os/Handler.html。 你可以向处理程序添加或删除消息,也许这可以帮助解决问题。 - Yaniv

0

最好的方法是使用哨兵:

runnable = new Runnable() {
    @Override
    public void run() {

    // condition to pass (sentinel == 1)
        if (isActive == 0) {
            handler.postDelayed(this, 1000); // 1 seconds
        }
        else {
        // isActive == 1, we pass!

        // Do something aweseome here!

        }


     }
};
handler = new Handler();
handler.postDelayed(runnable, 100);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接