简易精确计计时android代码,关于android:handler实现精确计时

首先说下对于handler本身的误差:

如果应用handler.postDealyed(……, 1000)形式来进行每秒的计时,是不精确的,是的,有很大误差,误差的起因在于在你收到音讯,到你从新收回handler.postDealyed的工夫,并不是霎时实现的,这外面有很多逻辑解决的工夫,即便没有逻辑解决的工夫,handler自身也是耗损性能的,所以音讯并不可能依照现实的1000提早来进行发送,这就导致了误差的累积。

代码:

时钟接口:

public interface IDigitalClock {

/**

* 开始计时

*/

void start();

/**

* 进行

*/

void stop();

/**

* 时钟复位

*/

void reset();

/**

* 重启

*/

void restart();

}

正计时时钟:

import android.os.Handler;

import android.os.Looper;

import android.os.Message;

import android.os.SystemClock;

import android.util.Log;

import java.text.DecimalFormat;

public class DefaultDigitalClock implements IDigitalClock {

private final static String TAG = "DefaultDigitalClock";

private final static int TICK_EVENT = 0x1001;

private Ticker mTicker;

private Handler handler = new Handler(new Handler.Callback() {

@Override

public boolean handleMessage(Message msg) {

if (msg.what == TICK_EVENT) {

long seconds = (long) msg.obj;

String HHMMss = formatElapsedTime(seconds);

clock.tick(seconds, HHMMss);

}

return false;

}

});

private long startTime;

private long elapsedSeconds;

private long maxSeconds;

private ClockOnMainThread clock;

public DefaultDigitalClock(ClockOnMainThread clock) {

this(-1, clock);

}

public DefaultDigitalClock(long maxSeconds, ClockOnMainThread clock) {

this.maxSeconds = maxSeconds;

this.clock = clock;

this.elapsedSeconds = -1;

this.startTime = -1;

}

@Override

public void start() {

startTime = System.currentTimeMillis();

mTicker = new Ticker();

long now = SystemClock.uptimeMillis();

long next = now + (1000 - now % 1000);

handler.postAtTime(mTicker, next);

}

@Override

public void stop() {

handler.removeMessages(TICK_EVENT);

if (mTicker != null) {

handler.removeCallbacks(mTicker);

}

}

@Override

public void reset() {

elapsedSeconds = -1;

startTime = -1;

handler.sendMessage(newTick(0));

}

@Override

public void restart() {

stop();

reset();

start();

}

/**

* 在每秒的整点执行

* {@link "https://blog.csdn.net/cpcpcp123/article/details/88542113"}

*/

private final class Ticker implements Runnable {

public void run() {

onTimeChanged();

// 在设定秒数后完结

if (maxSeconds > 0 && elapsedSeconds == maxSeconds) {

stop();

return;

}

long now = SystemClock.uptimeMillis();

long next = now + (1000 - now % 1000);

handler.postAtTime(this, next);

}

};

/**

* 计算工夫变动

*/

private void onTimeChanged() {

if (Thread.currentThread() != Looper.getMainLooper().getThread()) {

Log.e(TAG, "onTimeChanged() must work on main thread!");

return;

}

elapsedSeconds = (System.currentTimeMillis() - startTime) / 1000;

Log.d(TAG, String.valueOf(elapsedSeconds));

String HHMMss = formatElapsedTime(elapsedSeconds);

clock.tick(elapsedSeconds, HHMMss);

}

private Message newTick(long seconds) {

Message msg = new Message();

msg.what = TICK_EVENT;

msg.obj = seconds;

return msg;

}

/**

* @see android.text.format.DateUtils#formatElapsedTime(long)

* @param elapsedSeconds 通过的秒数

*/

private String formatElapsedTime(long elapsedSeconds) {

// Break the elapsed seconds into hours, minutes, and seconds.

long hours = 0;

long minutes = 0;

long seconds = 0;

if (elapsedSeconds >= 3600) {

hours = elapsedSeconds / 3600;

elapsedSeconds -= hours * 3600;

}

if (elapsedSeconds >= 60) {

minutes = elapsedSeconds / 60;

elapsedSeconds -= minutes * 60;

}

seconds = elapsedSeconds;

String hh = new DecimalFormat("00").format(hours);

String mm = new DecimalFormat("00").format(minutes);

String ss = new DecimalFormat("00").format(seconds);

return String.format("%s:%s:%s", hh, mm, ss);

}

public interface ClockOnMainThread {

void tick(long seconds, String time);

}

}

参考博客

handler实现准确计时的两种形式

Android计时罕用的7种形式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值