Handler postDelayed and Thread.sleep()

Jace picture Jace · Sep 10, 2013 · Viewed 17.5k times · Source

I have a thread.sleep and a handler postDelayed in my code:

handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        Log.e(TAG, "I ran");
        mIsDisconnect = false;
    }
}, DISCONNECT_DELAY);

After the handler code and after the user press the button I have this:

while (mIsDisconnect) {
    try {
        Thread.sleep(DELAY);
    } catch (InterruptedException e) {
        Log.e(TAG, "problem sleeping");
    }
}

If the user wait long enough I can get the "I ran" in my log. But if the user press the button before the delay is up, it seems that the postDelayed never gets a chance to execute. My question is, does the thread.sleep() mess with the handler postDelayed?

Edit: The purpose of this code is that I want to continue the program only after DISCONNECT_DELAY seconds has already passed. So if the user clicks to early, I have to wait for the elapsed time to finish.

Answer

laalto picture laalto · Sep 10, 2013

I'm assuming your handler is associated with the same thread the other loop is running on. (A Handler is associated with the thread it is created in.)

postDelayed() puts the Runnable in the handler thread's message queue. The message queue is processed when control returns to the thread's Looper.

Thread.sleep() simply blocks the thread. The control does not return to the Looper and messages cannot be processed. Sleeping in the UI thread is almost always wrong.

To accomplish what you're trying to do, remove the sleep and simply use postDelayed() to post a Runnable that changes your app state (like you already do by setting a member variable mIsDisconnect). Then in the onClick() just check the app state (mIsDisconnect flag) whether it is ok to proceed or not.