Reputation: 5308
I have developed a stopwatch in Android . The stopwatch has the feature of Lap calculation too.
I have started the stopwatch . I tested the stopwatch developed by me with multiple standard stopwatches . The problem is that after 1 minutes , the stopwatch developed keeps lagging behind the other stopwatches & the difference keeps on increasing. I got around 8-10 seconds lagging after the 3 minutes.
The following code I am using:
Two classes I am using , one for the Stopwatch implementation & the other for Stopwatch display
StopwatchImplementation.java
/** The timer used to implement the Stopwatch logic. */
private Timer mSWatch = null;
/**
* Starts the Stopwatch.
*/
public void watchStart() {
if (mSWatch != null)
mSWatch .cancel();
mSWatch = new Timer();
mSWatch .schedule(new TimerTask() {
@Override
public void run() {
mListener.updateUIThread();
}
}, 0, 100);
}
/** Runnable The Timer_ tick where the time is updated */
Runnable Timer_Tick = new Runnable() {
public void run() {
updateTime(); // Updates the time , calculates the lap duration
}
};
private int mHours = 0;
/** The mins. */
private int mMins = 0;
/** The secs. */
private int mSecs = 0;
/** The fraction of a sec. */
private int mFSec = 0;
/** The lap hours. */
private int mLapHours = 0;
/** The lap mins. */
private int mLapMins = 0;
/** The lap secs. */
private int mLapSecs = 0;
/** The lap fraction of sec.... 1/10th of a sec*/
private int mLapFSec = 0;
public void updateTime() {
try {
mLapFSec++;
if (mLapFSec >= 10) {
mLapFSec = 0;
mLapSecs++;
if (mLapSecs >= 60) {
mLapSecs = 0;
mLapMins++;
if (mLapMins >= 60) {
mLapMins = 0;
mLapHours++;
}
}
}
mFSec++;
if (mFSec >= 10) {
mFSec = 0;
mSecs++;
if (mSecs >= 60) {
mSecs = 0;
mMins++;
if (mMins >= 60) {
mMins = 0;
mHours++;
}
}
}
}
StopwatchScreen.java
StopwatchImplementation mStopWatch = new StopwatchImplementation(this);
/**
* Update ui thread.
*/
public void updateUIThread() {
StopWatchScreen.this.runOnUiThread(mStopWatch.Timer_Tick);
}
public void startPressed() {
mStopWatch.watchStart();
}
Kindly provide any inputs regarding where the calculation is going wrong.
Thanks in advance.
Warm Regards,
CB
Upvotes: 0
Views: 486
Reputation: 23432
You cannot rely on the scheduling of a TimerTask
for precision timing. You have asked for the updateTime
method to be called every 100 milliseconds, but the Android system will only adhere to this roughly - it might take 99 or 101 milliseconds before the next time updateTime
is called. Because of this you should avoid timing mechanisms which rely on simply increasing a counter.
For this reason you should record the start time, then compare the current time to the start time to get the amount of time elapsed. For instance:
private long startTime;
public void watchStart() {
startTime = SystemClock.elapsedRealtime();
...
}
public void updateTime() {
final long currentTime = SystemClock.elapsedRealtime();
final long elapsedTime = currentTime - startTime;
// convert elapsedTime in seconds, minutes etc
final int seconds = (elapsedTime/1000)%60;
final int minutes = (elapsedTime/(1000*60))%60;
final int hours = (elapsedTime/(100*60*60))%24;
...
}
Upvotes: 2