5

我的代码中有一个 thread.sleep 和一个处理程序 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");
    }
}

如果用户等待的时间足够长,我可以在我的日志中看到“我跑了”。但是如果用户在延迟结束之前按下按钮,似乎 postDelayed 永远没有机会执行。我的问题是,thread.sleep() 是否与处理程序 postDelayed 混淆?

编辑:这段代码的目的是我想在 DISCONNECT_DELAY 秒已经过去之后继续程序。因此,如果用户点击到早,我必须等待经过的时间才能完成。

4

3 回答 3

12

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

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

Thread.sleep()简单地阻塞线程。控件不返回Looper,消息无法处理。在 UI 线程中休眠几乎总是错误的。

要完成您要执行的操作,请删除 sleep 并简单地使用postDelayed()发布一个Runnable更改您的应用程序状态的内容(就像您已经通过设置成员变量所做的那样mIsDisconnect)。然后onClick()只需检查应用程序状态(mIsDisconnect标志)是否可以继续。

于 2013-09-10T08:04:12.930 回答
1

我猜第二部分在主线程上运行,你没有在线程之间移动。
你不能让主线程进入睡眠状态,你停止所有 UI 问题和其他应该在这个线程(主线程)上运行的东西。

改为使用postDelayed处理程序。

于 2013-09-10T07:35:40.700 回答
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);
于 2016-06-27T15:12:38.410 回答