Dan Stef
Dan Stef

Reputation: 773

Android postDelayed does not delay

I have the Problem that my Android app does not delay a second (or 10 seconds), if I use the postDelayed method..

Basically I would like my program to wait one second after I clicked the button, then update the text on my textview ("READY"), wait another 2 seconds, then update the textview again ("SET") and then it should start another activity (not yet implemented :-) ).

With my code, the programm starts and after I click the button the textview shows the last text ("SET") immediately.. It just does not wait.

What am i doing wrong?

Here is my code:

public class MyCounterActivity extends Activity {

private long mInternval = 100000;
private Handler mHandler;

private Runnable mStatusChecker = new Runnable() {
    @Override
    public void run() {
        //updateInterval(); //change interval
        startRepeatingTask();
    }
};

void startRepeatingTask(){
    mHandler.postDelayed(mStatusChecker, mInternval);
    //mStatusChecker.run();
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_gym_counter);

    final TextView tv1 = (TextView) findViewById(R.id.fullscreen_content);
    final Button startButton = (Button) findViewById(R.id.startbutton);

    startButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            final long up;
            EditText textUp = (EditText) findViewById(R.id.editTextUp);                
            up = Integer.parseInt(textUp.getText().toString());

            Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    //
                }
            },1000);
            Log.d("after 1 runnable", "whaaat");

            tv1.setText("Ready");
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    //
                }
            }, 2000);

            Log.d("after 2nd runnable", "whaaat 2");
            //startRepeatingTask();
            tv1.setText("SET");
        }
    });
}

I also tried to run it with the runOnUiThread() (within the onClick(View v) but with with the same result). I expected it to wait 1 second (startRepeatingTask()) and then runs the loop and waits several seconds...

                    runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        startRepeatingTask();
                            for (int u = 0; u < up; u++){
                                startRepeatingTask();
                            }
                        }
                    }
                });

Hope my description makes sense :-).

Thank you for your help!

EDIT: I was now able to find a solution for my first problem. The answer from @mad in this post helpded me: How to start a different activity with some delay after pressing a button in android? (Thats probably the same thing that @laalto tried to tell me. Thanks for the hint!)

In the onClick()

            tv1.setText("READY");
            mHandler.postDelayed(mDelay1, 2000);

And then the Runnable

    private Runnable mDelay1 = new Runnable() {
    @Override
    public void run() {
        if (tv1.getText()=="READY")
            tv1.setText("SET");
    }
};

BUT: If i want to refresh the text on my Textview after every second, how do i do that? I cant just call mHandler.postDelayed() several times.. Any help is appreciated.

Upvotes: 1

Views: 3420

Answers (2)

FrankKrumnow
FrankKrumnow

Reputation: 508

Whenever you call something like Thread.start(), handler.postDelayed, view.postDelayed, AsynchTask, TimerTask .. you enter the world of threading or you might call it parallel computing.

So there can be multiple threads ("codes") running at the same time.

When you are inside your Activity it is running in a Thread that is calld UI-thread or main thread. All graphics is handled in that thread and that thread alone.

Do NEVER wait in the UI-thread!

Example: you have a button that switches color from say gray to yellow on pressing it. Now you enter a Thread.sleep(10000); - waiting 10 seconds at the start of your onClick. You will then see that the button stays yellow (=pressed) for 10 seconds even if you only pressed very shortly. Also: if you overdo it android os will become angry and post the user if he wants to force-close your app.

So what happens on handler.postDelayed?

Android will very quickly open a thread that runs in the background parallel to your UI thread. So in some nanoseconds it has done that and will execute the next command in UI thread (in the example above it is Log.d). In the background it will wait and count the millis until time is up. Then any code that is inside the runnable.run method will again be executed in the ui-thread after the wait.

Note also: postDelayed will not be super precise with the wait time as usually the ui-thread is quite buisy and when the wait time is up it may have something else to do. Your runnable code will be added to a queue and executed when ui-thread is ready again. All this happens without you having anything to do about it.

Also: Remember to work with try/catch inside the runnable.run as many things can happen while waiting - for example user could press Home button closing your app - so the ui-element you wanted to change after the wait could already been destroyed.

Upvotes: 0

laalto
laalto

Reputation: 152827

When you call postDelayed(), it just places the Runnable in a queue and returns immediately. It does not wait for the runnable to be executed.

If you need something to happen after a delay, put the code in the run() method of the runnable.

Upvotes: 2

Related Questions