Jace
Jace

Reputation: 459

Handler postDelayed and Thread.sleep()

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.

Upvotes: 8

Views: 21322

Answers (3)

oskarko
oskarko

Reputation: 4178

The best way is with a sentinel:

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);

Upvotes: 0

laalto
laalto

Reputation: 152817

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.

Upvotes: 12

Yaniv
Yaniv

Reputation: 3381

I guess that the second section runs on the main thread and you didn't move between threads.
You can't put the main thread on sleep, you stop all UI issues and other stuff that should be run on this thread (the main thread).

Use postDelayed of the handler instead.

Upvotes: 1

Related Questions