如何避免两个 Chronometers 开始时间之间的毫秒差异?
How can I avoid the difference of milliseconds between two Chronometers start time?
我在 activity 中有两个 Chronometer。
第一个计时表是经过时间,第二个计时表是间隔时间。
例如:-
我们选择了 5 分钟经过时间和 30 秒间隔时间,现在我们通过按 btn_start 同时启动两个计时器。两个计时器都从 0 开始,现在当间隔计时器达到 00:30 时间时,它会再次以 0.
重新启动
现在问题:-
正如我交叉检查的那样,两个计时器的启动时间相差几毫秒。后来变成1秒,2秒,3秒或更多秒的差异。
以下是自定义 Chronometer.Java
public class PausableChronometer extends Chronometer implements PlaybackStateView {
// Keeps track of how far long the Chronometer has been tracking when it's paused. We'd like
// to start from this time the next time it's resumed.
private long timeWhenStopped = 0;
public PausableChronometer(Context context) {
super(context);
}
public PausableChronometer(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PausableChronometer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void start() {
setBase(SystemClock.elapsedRealtime() + timeWhenStopped);
Log.e("start()", String.valueOf(SystemClock.elapsedRealtime() + timeWhenStopped));
super.start();
}
@Override
public void stop() {
super.stop();
timeWhenStopped = getBase() - SystemClock.elapsedRealtime();
}
/**
* Reset the timer and start counting from zero.
*/
@Override
public void restart() {
reset();
start();
}
public void reset() {
stop();
setBase(SystemClock.elapsedRealtime());
timeWhenStopped = 0;
}
@Override
public void resume() {
setBase(SystemClock.elapsedRealtime() - timeWhenStopped);
start();
}
@Override
public void pause() {
stop();
timeWhenStopped = SystemClock.elapsedRealtime() - getBase();
}
}
点击按钮我执行以下操作:
private void startTimer() {
intervalTimer.start();
elapsedTimer.start();
}
请告诉我,如何避免两个计时器开始时间之间的毫秒差异?
正如 Anton Malyshev 所说,避免两个不同计时器的开始时间不同是不可能的。
我使用 Handler 和 Runnable 解决了这个问题,对我来说,它工作得很好。
private TextView elapsedTimer, intervalTimer;
Handler mHandlerElapsed = new Handler(), mHandlerInterval = new Handler();
Runnable mRunnableElapsed, mRunnableInterval;
private int nCounterInterval = 0, nCounterElapsed = 0;
定时器方法:-
private void updateTime() {
mHandlerElapsed = new Handler();
mRunnableElapsed = new Runnable() {
@Override
public void run() {
if (!isPause) {
mHandlerElapsed.postDelayed(mRunnableElapsed, 1000);
nCounterElapsed++;
elapsedTimer.setText(AppUtil.formattedTime(nCounterElapsed));
} else {
mHandlerElapsed.removeCallbacks(mRunnableElapsed);
}
}
};
mHandlerElapsed.post(mRunnableElapsed);
mHandlerInterval = new Handler();
mRunnableInterval = new Runnable() {
@Override
public void run() {
if (!isPause) {
mHandlerInterval.postDelayed(mRunnableInterval, 1000);
nCounterInterval++;
intervalTimer.setText(AppUtil.formattedTime(nCounterInterval));
} else {
mHandlerInterval.removeCallbacks(mRunnableInterval);
}
}
};
mHandlerInterval.post(mRunnableInterval);
}
用于启动和暂停计时器:-
private void startTimer() {
isPause = false;
updateTime();
}
private void pauseTimer() {
isPause = true;
updateTime();
}
在AppUtil.java
public static String formattedTime(int totalSeconds) {
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
if (totalSeconds >= 3600) {
minutes = minutes + 60;
}
return String.format(Locale.US, "%02d:%02d", minutes, seconds);
}
使用上述解决方案,我的问题得到解决。
我在 activity 中有两个 Chronometer。 第一个计时表是经过时间,第二个计时表是间隔时间。
例如:- 我们选择了 5 分钟经过时间和 30 秒间隔时间,现在我们通过按 btn_start 同时启动两个计时器。两个计时器都从 0 开始,现在当间隔计时器达到 00:30 时间时,它会再次以 0.
重新启动现在问题:- 正如我交叉检查的那样,两个计时器的启动时间相差几毫秒。后来变成1秒,2秒,3秒或更多秒的差异。
以下是自定义 Chronometer.Java
public class PausableChronometer extends Chronometer implements PlaybackStateView {
// Keeps track of how far long the Chronometer has been tracking when it's paused. We'd like
// to start from this time the next time it's resumed.
private long timeWhenStopped = 0;
public PausableChronometer(Context context) {
super(context);
}
public PausableChronometer(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PausableChronometer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void start() {
setBase(SystemClock.elapsedRealtime() + timeWhenStopped);
Log.e("start()", String.valueOf(SystemClock.elapsedRealtime() + timeWhenStopped));
super.start();
}
@Override
public void stop() {
super.stop();
timeWhenStopped = getBase() - SystemClock.elapsedRealtime();
}
/**
* Reset the timer and start counting from zero.
*/
@Override
public void restart() {
reset();
start();
}
public void reset() {
stop();
setBase(SystemClock.elapsedRealtime());
timeWhenStopped = 0;
}
@Override
public void resume() {
setBase(SystemClock.elapsedRealtime() - timeWhenStopped);
start();
}
@Override
public void pause() {
stop();
timeWhenStopped = SystemClock.elapsedRealtime() - getBase();
}
}
点击按钮我执行以下操作:
private void startTimer() {
intervalTimer.start();
elapsedTimer.start();
}
请告诉我,如何避免两个计时器开始时间之间的毫秒差异?
正如 Anton Malyshev 所说,避免两个不同计时器的开始时间不同是不可能的。
我使用 Handler 和 Runnable 解决了这个问题,对我来说,它工作得很好。
private TextView elapsedTimer, intervalTimer;
Handler mHandlerElapsed = new Handler(), mHandlerInterval = new Handler();
Runnable mRunnableElapsed, mRunnableInterval;
private int nCounterInterval = 0, nCounterElapsed = 0;
定时器方法:-
private void updateTime() {
mHandlerElapsed = new Handler();
mRunnableElapsed = new Runnable() {
@Override
public void run() {
if (!isPause) {
mHandlerElapsed.postDelayed(mRunnableElapsed, 1000);
nCounterElapsed++;
elapsedTimer.setText(AppUtil.formattedTime(nCounterElapsed));
} else {
mHandlerElapsed.removeCallbacks(mRunnableElapsed);
}
}
};
mHandlerElapsed.post(mRunnableElapsed);
mHandlerInterval = new Handler();
mRunnableInterval = new Runnable() {
@Override
public void run() {
if (!isPause) {
mHandlerInterval.postDelayed(mRunnableInterval, 1000);
nCounterInterval++;
intervalTimer.setText(AppUtil.formattedTime(nCounterInterval));
} else {
mHandlerInterval.removeCallbacks(mRunnableInterval);
}
}
};
mHandlerInterval.post(mRunnableInterval);
}
用于启动和暂停计时器:-
private void startTimer() {
isPause = false;
updateTime();
}
private void pauseTimer() {
isPause = true;
updateTime();
}
在AppUtil.java
public static String formattedTime(int totalSeconds) {
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
if (totalSeconds >= 3600) {
minutes = minutes + 60;
}
return String.format(Locale.US, "%02d:%02d", minutes, seconds);
}
使用上述解决方案,我的问题得到解决。