I have a set of instructions that needs to be executed repeatedly.
The repeat delay is variable (the delay is taken from a file).
The repeat time must be very precise (milliseconds precision).
I have tried to use a Handler with postDelayed but the accuracy is lost in time. This happens because the repeat frequency is more than 10 times/second.
Any idea is more than welcomed!
Here is the Handler example:
new Runnable() {
#Override
public void run() {
mHandler.postDelayed(this, delay);
barometerResult.gotBarometer(barometerValueModelList.get(i).getBarometerValue());
}
}.run();
I don't think it's a good idea using Handler, it runs in the UI thread with many other things to do in the queue, so that's not guarantee your runnable code would be executed so precisely.
If your work in the Runnable is just some logic task not involved in update UI.Consider using a Timer to do that but be ware that it will run on a separated thread.
Related
What is the best way to delay a method call without freezing the UI or running of the program? I want to display circles on the screen every 5 seconds but in those 5 seconds, other existing circles will be changing size so the drawcircle method has to be called every 5 seconds but other code has to be able to run too.
Use Handler for it:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//any delayed code
}
}, 5000);
Causes the Runnable to be added to the message queue, to be run after the specified amount of time elapses. The runnable will be run on the thread to which this handler is attached. The time-base is in milliseconds, in eg above it is 5000 milliseconds.
The postDelayed takes two parameters:
The Runnable that will be executed.
The delay (in milliseconds) until the Runnable will be executed.
Use Handler's method called postDelayed.
For more info, read this.
So, there are multiple similar questions/answers about how to do a delay on Android. However they mostly focus on doing this on UI thread.
What if I need a delay in a worker thread in a service (and I don't want to put the thread to sleep)? the Handler.postDelayed() doesn't work as there is a "can't create a handler inside thread has not called Looper.prepare()" exception. CountDownTimer doesn't work for the same reason. And I don't have any views to call runOnUiThread().
So is the only solution to have a looper on each thread I have or there is another way to do this?
UPDATE:
It's silly, but I found the answer working for me in my own old code :).
Basically, if you want to start a Runnable with a delay from a non-UI thread, all you need to do is ask the main looper to handle this.
Handler handler = new Handler(Looper.getMainLooper());
Runnable r = new Runnable() {
#Override
public void run() {
// Do stuff to be run after a delay
// CAUTION: this won't be run on the same thread
}
};
handler.postDelayed(r, DELAY_TIME);
The drawback could be that the code in that Runnable will not be run on the same thread as the original code. This is why I'm not putting this approach as an answer to be accepted (I admit, the original question sounded like I want a timed event to happen on the same non-UI thread. For this I don't have an answer yet except the one from Emmanuel that I must attach a Looper to my thread). For my purposes however this works as I only need to start a service upon timeout.
Like you have seen from the Exceptions in order to use Handlers in a Thread you need to attach the Thread to the Looper. To give a bit more context, when you call postDelay() you are posting a message to the Thread's MessageQueue; the Looper is responsible for managing this Queue. So if you want to go the Handler route you will need to set up the Thread with a Looper.
If you want to delay the Thread without making it sleep() (I do not know why you cannot use sleep()) you can have a while that runs until a certain time from now has elapsed. (This sounds like a horrible idea).
I am having a service in my application that puts a runnable (in another java file) in a thread and starts it.
That is working fine for once, but i want it to be repetitive due to a certain period.
I need a good way to handle that.
Reason why I didn't use the answers to other questions is that I don't want it to repeat infinity nor I know how many times it'll repeat the task. It'll simply stop due to a button click in the UI.
I was thinking of using a loop with a sleep and if statement. But I think that's really bad design for my application. Is there a standard way for doing such thing?
Thanks...
You can use a handler that somehow acts like a timer but I think it is better for your situation.
You initialize it like this:
Handler delayhandler = new Handler();
Set the time it fires like this (in ms):
delayhandler.postDelayed(mUpdateTimeTask, 500);
And it calls this:
private Runnable mUpdateTimeTask = new Runnable()
{ public void run()
{ // Todo
// This line is necessary for the next call
delayhandler.postDelayed(this, 100);
}
}
You can also remove the next call with:
delayhandler.removeCallbacks(mUpdateTimeTask);
Use a TimerTask and have it execute your thread/method.
http://android.okhelp.cz/timer-simple-timertask-java-android-example/
http://developer.android.com/reference/java/util/TimerTask.html - You can use the Cancel() method to stop the TimerTask from executing.
Use the Timer it will run the thread after a given time period and when you want to stop just stop timer or set it to infinite time period.
I am looking for the method to update the screen at a constant rate, say every 50mSec.
In the embedded world I would configure a timer to trigger an interrupt every 50mSec and the ISR would handle the update. What I have in mind for Android is to have a FrameLayout with a number of view items registered to react to some sort of callback from a timer function.
Hopefully someone will understand my question and point me in the right direction.
You may use handler.postDelayed in a Runnable to call it after certain time period.
For example:
handler.post(new Runnable() {
#Override
public void run() {
handler.postDelayed(this, 50);
//do your task
}
});
Make sure you handler is attached to a separate (non-UI) thread and when it comes to update UI elements you always do it on a UI thread.
I am a new Android developer. I am using the Handler class to schedule some operations. So I am creating runnable objects that calls some of my instance methods.
But I have a problem. Sometimes my run() method in Runnable object is called twice.
What could be the problem??
and there is the code
//deneme is a Handler.
deneme.postDelayed(new Runnable() {
#Override
public void run()
{
randomOyna();
//the instance method that I call.
}
}, 1000);
If don't schedule your Handler to run on another Thread than the UI-thread, there might be a hidden delay in the execution because your Runnable will also run on the UI-thread and thus will only be allowed to run when there is "time" for it. With this hidden delay, it might seem like it is run twice but in reality it's just and over-delayed running before a regular delayed Runnable.
Can't see a mistake just by looking the hint you gave us... But you might try plain old java to run threads instead of handler... Good luck...
Look here for more details