I want to run some code for 20 seconds precisely. It is similar to a loop but instead of having a variable I have time (in seconds).
I should have a time condition like this:
do
{ variable++ }
while (sec < 20)
How it is possible to do this in Android??
My application should run this 20 sec code after the user presses a button.
You can use the Handler class in Android on a runnable and then use the postDelayed() method. That way you will be able to update the UI during that 20 seconds on the progress of the thread. A good example of this is hear. Your code might look something like this ...
Handler handler = new Handler();
final Runnable r = new Runnable(){
public void run() {
//Do thing after 20 sec
}
};
handler.postDelayed(r, 20000);
Related
Basically, I am trying to do something more complicated than that, but this is my problem:
When using handler.postDelayed inside a for loop, there's delay only on the first time, and I wait the delay to kick in every time the for loop repeats:
For example, in this case:
for(int z=0; z<4; z++) {
final int finalZ = z;
handler.postDelayed(new Runnable() {
#Override
public void run() {
Toast.makeText(play.this, "z:" + finalZ, Toast.LENGTH_SHORT).show();
}
}, 5000);
}
I will get:
Waiting 5 seconds.
z:0
z:1
z:2
z:3
What I want to get:
Waiting 5 seconds.
z:0
Waiting 5 seconds.
z:1
Waiting 5 seconds.
z:2
Waiting 5 seconds.
z:3
I was told not to use Thread.sleep() because it can cause various issues (I didn't quite understand them as I am new to android studio). I am using this in a certain activity (not my Main_Activity).
I am basically trying to change an image's color ever 0.5 seconds or so (more complications go into that, but that's the main idea). Will Thread.sleep() be better?
EDIT: Okay, so thanks to #tynn & #pskink I got this to work (see their answers). But now, another problem came up following this.
If, for example, I will run the exact same code after that, they will both run at the same time, and not one after another, how can i make the second "for" start only after the first "for" has ended?
Here another aspect
private int z=0;
Runnable r = new Runnable() {
#Override
public void run() {
Toast.makeText(play.this, "z:" + z, Toast.LENGTH_SHORT).show();
if(z<4){
z++;
handler.postDelayed(r, 5000);
}
}
}
handler.post(r);
The handler runs your code on another thread, independent of your for loop. The delay is relative to the point where you posted the runnable. Not relative to the previous post. Also it doesn't block the for loop at all. That's the purpose of handlers.
You can assume that any post in this scenario happens at the same time, so you could just do handler.postDelayed(runnable, (z + 1) * 5000). Or maybe define the execution time as absolute with handler.postAtTime(runnable, firstRun + z * 5000)
But since you're trying to do something more complicated than that, you should better consider using a Timer or similar. Maybe RxJava.
Your current code works like this:
hey handler, do it after 5s,
oh and do it after 5s too,
and do it after 5s too,
and this plz do after 5s.
Then we wait 5s and handler is doing those actions in one moment.
What you can do is change it to:
hey handler, do it after 5s,
oh and do it after 10s,
and this after 15s
...
Or you can do it like this:
hey handler do it after 5s, where 'it' action is 'hey handler do it after 5s'.
Then handler will wait 5s and call action 'hey handler do it after 5s'. So handler will have to wait again 5s and do some action after that time.
Here is code for my aproach:
final int finalZ = z;
delayedAction(handler, 0, z);
. . .
void delayedAction(final Handler handler, final int i, final int max) {
if(i<max) {
Toast.makeText(play.this, "z:" + finalZ, Toast.LENGTH_SHORT).show();
handler.postDelayed(new Runnable() {
#Override
public void run() {
delayedAction(handler, i+1, max);
}
});
}
}
I wonder what the best way is to implement this behavior:
I have an event X with an id that happens from time to time.
If the event with a certain id happened, I want to execute some code after 25 seconds, except if X with the same id happens again, in that case I want it to be postponed again with 25 seconds.
What is the best way to implement this?
Here is how you can use a simple handler to delay running something for 25 seconds. It's up to you to figure out how to filter on some ID.
Handler handler = new Handler();
public void myEvent() {
// Remove any callback that may be registered, this will reset it if called before
handler.removeCallbacks(runMe);
// Execute the runnable in 25 seconds
handler.postDelayed(runMe, 25000);
}
Runnable runMe = new Runnable() {
#Override
public void run() {
// This will run after the postDelayed expires in 25 seconds
Log.d("TAG", "Run me at some time");
}
};
I need to execute a method every 5 minutes. My problem is where? or How? could be to start the application but did not realize that. Any recommendations?
I don't know how BuzzBox works but I would create a Runnable, then call your method inside it every 5 minutes; That of course uses postDelayed method.
Handler handler = new Handler();
private Runnable updateTimerThread = new Runnable() {
public void run() {
//do call your method here; every 5 minutes
customHandler.postDelayed(this, 5000);
}
};
//you can use your handler anywhere you want like this
handler.postDelayed(updateTimerThread, 5000);
I'm trying to create a timer, that after the timer ends, will call a function...
For example, I have the function Foo. I want to create a timer, that after 1.5 seconds will call it..
Something like :
Timer(Foo(), 2000);
I have found this code :
private Handler handler = new Handler(); // Creating new handler
handler.postDelayed(runnable, 1500); // Creating a timer for 1.5 seconds
and this function :
private Runnable runnable = new Runnable()
{
#Override
public void run()
{
Foo();
handler.postDelayed(this, 1500);
}
};
My problem is, that some times the timer works perfect, usually for the first 2~3 times, and after that, Instead of being a 1.5sec timer, it become something like 0.3sec timer (and the more handler.postDelayed(runnable, 1500); is being called, the less time the timer will last (like, wont wait 1.5sec to call Foo, but much less)
Why is that ?
I know that in C++ if I write Console Applications, I can use Sleep.. Maybe I can just do something like this :
Sleep(1500);
Foo();
Thanks!
Edit: I have answered my own question.
You could use the Timer class in Android, and set a repeating timer, with a initial delay.
Timer timer = new Timer();
timer.schedule(TimerTask task, long delay, long period)
A TimerTask is very much like a Runnable.
See: http://developer.android.com/reference/java/util/Timer.html
I've used 2 timers :
handler.postDelayed(runnable, 1500); // Creating a timer for 1.5 seconds
this created a 1.5sec timer, while inside the timer loop :
private Runnable runnable = new Runnable()
{
#Override
public void run()
{
Foo();
handler.postDelayed(this, 1500);
}
};
I called handler.postDelayed(this,1500); again, which made 2 timers -> causing the time bug.
I'm using a runnable in my Android app to update a countdown timer, as shown in the code below. It appears to work but I noticed my timer takes a few seconds longer than expected. For example, if it's supposed to count down 3 minutes, it takes 3 minutes and 5 seconds. I tried using a timer in a service to manage the countdown display in the main activity. The timer/service worked as expected.
Why doesn't runnable/postDelayed() run for the correct amount of time? Is postDelayed() timing reliable? The runnable decrements a variable then uses it to update an EditText with setText(). Does setText() take too long (a small fraction of a second), so the runnable really runs every 1.x seconds?
Handler handler = new Handler();
Runnable r = new Runnable() {
public void run() {
// decrement the time remaining and update the display
handler.postDelayed(this, 1000);
}
};
...
// start the runnable
handler.postDelayed(r, 1000);
Your code is kinda sorta designed to be inaccurate because you are not accounting for the time taken by the guts of the runnable. You might get improved results by doing something like
public void run(){
startTime = System.currentTimeMillis();
// compare expectedTime to startTime and compensate
// <guts of runnable goes here>
// now wrap it up...
delay = 1000 - (System.currentTimeMillis() - startTime);
if (delay < 0)
delay = 0;
expectedTime = System.currentTimeMillies() + delay;
handler.postDelayed(this, delay);
}
What about using CountDownTimer? I used this for same tasks several times and haven’t met this kind of problem.