I have been using 5 Handler tasks in my application with different post delays but all of them are working at a different speed irrespective of the delay time that I have specified, is there a better way to get exact time delay in between of multiple tasks,
Sample Code:
H2 = new Handler();
R2 = new Runnable()
{ #Override
public void run()
{ H2.postDelayed(R2, 100);
//Do something
}
};
H2.postDelayed(R2, 0);
Task would run in variable time intervals sometimes way more variable.
I am using mhandler.postDelayed(runnable,5000) to write data to a file for every 5 seconds.
When the screen is off, I observed from the file the timing for the postDelayed(runnable,5000).
It is accurate for sometime but after for one hour, the timing for postDelayed(runnable,5000) increase to 10secs.
After two hour, the timing for postDelayed(runnable,5000) increase to 15secs.
After three hour, the timing for postDelayed(runnable,5000) increase to 20secs and so on..
It seems very strange that the postDelayed trigger timing changes with time.
Am I expecting this or there is a error in my code?
You should try to use something else than a Handler.
Try a Timer :
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...Perform a task...
}
};
new Timer(delay, taskPerformer).start();
I'm working on a presentation app, which displays different images. There I wanted to to let the presentation slide through my List of images, video and pdf files, after a short amount of time.
I start my different views through intents, startActivityForResult(intent, RESULT_OK);
Starting videos and closing videos was not an issue. I used onPreparedListener and setOnCompletionListener and everything worked like a charm.
With pictures however, this was completely diffrent.
I created a new Thread in my ImageView and did put that thread to sleep(), after that I called the setresult() method and finish(). But instead of waiting, the picture wasn't shown at all and the presentation was stuck there, without setting the result and finishing the activity.
So I started searching for some explanation of time in android and found this explanation:
Explanation
I read through it and tried to get a good grasp on whats explained there. But the more I thought about it, the more I got insecure, which is the best way to implement the waiting behavior for my intended purpose.
So instead of some code, I am much more interested in, what you would advise me to use and why with a, if possible, detailed explanation.
elapsedRealtime()?
uptimeMillis()?
System.currentTimeMillis()?
From android docs:
• System.currentTimeMillis() is the standard "wall" clock (time and date) expressing milliseconds since the epoch. The wall clock can be set by the user or the phone network (see setCurrentTimeMillis(long)), so the time may jump backwards or forwards unpredictably. This clock should only be used when correspondence with real-world dates and times is important, such as in a calendar or alarm clock application. Interval or elapsed time measurements should use a different clock. If you are using System.currentTimeMillis(), consider listening to the ACTION_TIME_TICK, ACTION_TIME_CHANGED and ACTION_TIMEZONE_CHANGED Intent broadcasts to find out when the time changes.
• uptimeMillis() is counted in milliseconds since the system was booted. This clock stops when the system enters deep sleep (CPU off, display dark, device waiting for external input), but is not affected by clock scaling, idle, or other power saving mechanisms. This is the basis for most interval timing such as Thread.sleep(millls), Object.wait(millis), and System.nanoTime(). This clock is guaranteed to be monotonic, and is suitable for interval timing when the interval does not span device sleep. Most methods that accept a timestamp value currently expect the uptimeMillis() clock.
• elapsedRealtime() and elapsedRealtimeNanos() return the time since the system was booted, and include deep sleep. This clock is guaranteed to be monotonic, and continues to tick even when the CPU is in power saving modes, so is the recommend basis for general purpose interval timing.
If the time interval, you're going to measure, is relatively short, you can use pretty much any method which gives you correct time. I prefer currentTimeMillis(). In case the time interval is really long, the recommended method is to use elapsedRealtime().
Also, if you only want to do something with a delay, simply use: http://developer.android.com/reference/android/os/Handler.html#postDelayed(java.lang.Runnable, long) . It's simple and works great.
Simplest way to achieve that is CountDownTimer
private final class CountDownTimerImpl extends CountDownTimer {
//5 sec.
private static final long TIME_INTERVAL = 5000;
private final ImageView imageView;
private final List<Drawable> images;
public CountDownTimerImpl(ImageView imageView, List<Drawable> images) {
super(TIME_INTERVAL, TIME_INTERVAL);
this.imageView = imageView;
this.images = images;
//set first image from images array to imageView
imageView.setImageDrawable(images.get(0));
}
//this method is executed after TIME_INTERVAL (5 sec.)
public void onFinish() {
//remove drawable from imageView
imageView.setImageDrawable(null);
//remove this drawable from array
images.remove(0);
//if array is not empty start another count down
if (!images.isEmpty()) {
new CountDownTimerImpl(imageView, images).start();
}
}
public void onTick(long millisUntilFinished) {
//nothing to do here
}
}
You should start this CountDownTimer by:
new CountDownTimerImpl(imageView, images).start();
where images is of course an drawables array of your presentation images.
I have no time to test this solution but it should work - if not please leave a comment and I will update it later.
You can use TimerTask
int counter=0;
final Handler handler = new Handler();
Timer ourtimer = new Timer();
TimerTask timerTask = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
counter++;
//you can do stuffs here say like if (counter==15) { do something}
}
});
}};
ourtimer.schedule(timerTask, 0, 1000);
You can do this in a different way writing a callback module
Create a activity call it BaseActivity and let all you activities to extend it
Now declare a method call is void callback(){} keep the body empty
now in onCreate create a timer as above and call the callback function your code will look like
onCreate(){
final Handler handler = new Handler();
Timer callTimer = new Timer();
TimerTask timerTask = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
callback();
}
});
}};
callTimer.schedule(timerTask, 0, 1000);
}
Now in you activity override the callback method which will be called after the time you specified in timer,
Ex
Class a extends BaseActivity(){
#Override
onCreate(){
// playVideo
}
#Override
void onCallBack(){
//navigate to another activity
}
}
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.
I have an android app that repeatedly collects fingerprints from the wifi-networks that are around (for scientific reasons, not to invade anybodies privacy).
Anyways, imagine I have a function that does this work and it's called scanWifi(). I initally wanted to start it like this:
ExecutorService mExecutor = Executors.newSingleThreadScheduledExecutor();
mExecutor.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
scanWifi();
}
}, 0, interval, TimeUnit.MILLISECONDS);
Sadly, this only works reliably when the phone is plugged in. If it's plugged out and lays there for a while, it doesn't run my scanWifi() function every minute. Sometimes there are gaps of several minutes between single calls to scanWifi().
I also tried doing the same thing using a Timer/TimerTask with similarly poor results.
The only thing that seems to work more or less reliable until now is to post it to a handler and call it repeatedly, like this:
Handler h = new Handler();
Runnable r = new Runnable() {
#Override
public void run() {
if (!mIsStopped) {
scanWifi();
h.postDelayed(this, mInterval);
}
}
};
h.post(r);
Why is that the case? Is the CPU sleeping and thus misses the scheduled execution? I hold a partial wakelock in my app.
I think what you're looking for is an AlarmManager. See, for example, this question: Android: How to use AlarmManager