Reputation: 773
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
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
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