george
george

Reputation: 1386

Android wait() not working

This is my first question here, so please forgive me if I disobeyed any of the forum rules.

I need my program to wait for 3 seconds and then change the Content View

My code is:

setContentView(R.layout.logout); 

new Thread(new Runnable() { 
    @Override 
    public void run(){ 
        try { 
           synchronized(this){ 
                wait(3000);
            } 
        } 
        catch(InterruptedException ex){                     
        }            
    } 
}).start();

setContentView(R.layout.main);

The program works with no errors, but there is no waiting. When it gets to this part, it just shows the "main" layout without showing the "logout" layout at all.

What is wrong in my approach?

Upvotes: 5

Views: 7396

Answers (5)

Kiran Babu
Kiran Babu

Reputation: 1893

Your code not work to sleep UI thread.To sleep UI thread try this code

new Handler().postDelayed(new Runnable() 
{ 
    public void run() 
    { 
        setContentView(R.layout.main);
    }
}, 3000);

Upvotes: 3

Philipp Reichart
Philipp Reichart

Reputation: 20961

As people noted, don't sleep on or otherwise block the UI thread, but you seem to be aware of this with the new thread you create.

Now for why it doesn't behave as you want:

Right now, you call setContentView(), start a new thread, call setContentView() a second time on the UI thread -- this happens in quick succession with no delay/wait/sleep inbetween. The wait(3000) happens in the new thread you started -- so that new thread starts, waits for 3000ms, then exits. It's an expensive no-op.

You would need to make the second call to setContentView() from inside that new thread's run() method to get the desired effect. Also, you should use sleep() instead of wait() -- wait() is a low-level tool for synchronizing threads while sleep() is the usual "don't continue for X amount of time".

Let me propose a better way:

An arguably nicer and much lighter approch is using Handler.postDelayed() -- this allows you to invoke a Runnable on the UI thread after a delay:

setContentView(R.layout.logout);
new Handler().postDelayed(new Runnable() {
    @Override
        public void run() {
            setContentView(R.layout.main);
        }
    }, 3000);

Edit to reply to your comment:

Define and find the button before the Runnable as a final variable, this way you can access it later from inside the Runnable.

Please note that to reference the this instance of the surrounding class from inside an anonymous inner class (your new Runnable()), you need to prefix it with the class name of the surrounding class (your Activity class):

final View submitButton = findViewById(R.id.submit_button); 
setContentView(R.layout.logout);
new Handler().postDelayed(new Runnable() {
    @Override
        public void run() {
            setContentView(R.layout.main);
            // adapt to your actual Activity class name:
            submitButton.setOnClickListener(YourClassName.this);
        }
    }, 3000);

Upvotes: 10

Till Helge
Till Helge

Reputation: 9311

wait() doesn't wait for a certain amount of time, but rather has the current Thread wait for this to do a notify() for a maximum amount of time. What you are looking for, is Thread.sleep().

And at the moment the only thing that will be waiting, is the additional thread you are spawning, not the activity itself. That's why I'd suggest you look at Handler.postDelayed(), CountDownTimer or AsyncTask. Handling threads is very low-level.

Upvotes: 5

Rajdeep Dua
Rajdeep Dua

Reputation: 11230

As far as i can understand the wait is happening in the new thread where as you are calling setContentView(R.layout.main) in the current thread.

Try

setContentView(..)
synchronized(this) {
    this.wait(1000);
}
setContentView(..)

Please note sleeping or waiting in the UI thread is not a best practice though.

Upvotes: 0

Raoul George
Raoul George

Reputation: 2797

Try using Sleep() instead of Wait()

android.os.SystemClock.sleep(3000)

Upvotes: 0

Related Questions