android 计时器 三种,Android计时器的三种实现方式(Chronometer、Timer、handler)

本文介绍了三种实现Android计时器的方法:使用Timer、Handler及Chronometer组件。通过具体实例展示了每种方法的布局文件及Activity代码,并分析了Chronometer组件的格式设置问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文实例为大家分享了android计时器的三种方法,具体内容如下

目录:

1、借助timer实现

2、调用handler.sendmessagedely(message msg, long delaymillis)

3、借助布局chronometer

1、借助timer实现

(1) 布局文件

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

android:id="@+id/timerview"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"

android:textsize="60sp" />

布局文件很简单,就是一个textview用来显示计时时间。下面看一下activity里的逻辑实现:

(2)activity文件

public class mychronometer extends activity {

private textview timerview;

private long basetimer;

@override

protected void oncreate(bundle savedinstancestate) {

setcontentview(r.layout.chrono);

mychronometer.this.basetimer = systemclock.elapsedrealtime();

timerview = (textview) this.findviewbyid(r.id.timerview);

final handler starttimehandler = new handler(){

public void handlemessage(android.os.message msg) {

if (null != timerview) {

timerview.settext((string) msg.obj);

}

}

};

new timer("开机计时器").scheduleatfixedrate(new timertask() {

@override

public void run() {

int time = (int)((systemclock.elapsedrealtime() - mychronometer.this.basetimer) / 1000);

string hh = new decimalformat("00").format(time / 3600);

string mm = new decimalformat("00").format(time % 3600 / 60);

string ss = new decimalformat("00").format(time % 60);

string timeformat = new string(hh + ":" + mm + ":" + ss);

message msg = new message();

msg.obj = timeformat;

starttimehandler.sendmessage(msg);

}

}, 0, 1000l);

super.oncreate(savedinstancestate);

}

新开一个定时器(timer), 在子线程中获取开机时间并转成字符串格式, 利用handler传回ui线程显示。

(3)运行结果:

82f6e13dfa3b978a88ed0326f5dc5866.png

2.调用handler.sendmessagedely(message msg, long delaymillis)

(1) 布局文件与方法1 相同,运行结果与方法1 相同

(2)activity文件

public class mychronometer extends activity {

private textview timerview;

private long basetimer;

@override

protected void oncreate(bundle savedinstancestate) {

setcontentview(r.layout.chrono);

mychronometer.this.basetimer = systemclock.elapsedrealtime();

timerview = (textview) this.findviewbyid(r.id.timerview);

handler myhandler = new handler(){

public void handlemessage(android.os.message msg) {

if (0 == mychronometer.this.basetimer) {

mychronometer.this.basetimer = systemclock.elapsedrealtime();

}

int time = (int)((systemclock.elapsedrealtime() - mychronometer.this.basetimer) / 1000);

string hh = new decimalformat("00").format(time / 3600);

string mm = new decimalformat("00").format(time % 3600 / 60);

string ss = new decimalformat("00").format(time % 60);

if (null != mychronometer.this.timerview) {

timerview.settext(hh + ":" + mm + ":" + ss);

}

sendmessagedelayed(message.obtain(this, 0x0), 1000);

}

};

myhandler.sendmessagedelayed(message.obtain(myhandler, 0x0), 1000);

super.oncreate(savedinstancestate);

}

sendmessagedelayed (message msg, long delaymillis):在 delaymillis/1000 秒后发送消息 msg。

在handler 的 handlemessage()方法中调用sendmessagedelayed方法, 巧妙的实现了循环。需要注意的是,在handler外要调用一次starttimehandler.sendmessagedelayed(message.obtain(starttimehandler, 0x0), 1000);  以作为循环的入口。

3.借助布局chronometer

(1) 布局文件

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

android:id="@+id/chronometer"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"

android:textsize="60sp" />

布局chronometer继承自textview

(2)activity文件

public class mychronometer extends activity {

chronometer chronometer;

@override

protected void oncreate(bundle savedinstancestate) {

setcontentview(r.layout.chrono);

chronometer = (chronometer) this.findviewbyid(r.id.chronometer);

chronometer.setbase(systemclock.elapsedrealtime());

chronometer.start();

super.oncreate(savedinstancestate);

}

}

逻辑代码很简单,调用chronometer.start()就可以开始计时。

chronometer.setbase(long base):设置起始计时点,这里设置的是获取开机时间。

chronometer.start():以上面setbase()设置的时间点为起始点,开始计时,看一下start()的源码就知道了:

public void start() {

mstarted = true;

updaterunning();

}

调用了updaterunning(), 跟入updaterunning()方法:

private void updaterunning() {

boolean running = mvisible && mstarted;

if (running != mrunning) {

if (running) {

updatetext(systemclock.elapsedrealtime());

dispatchchronometertick();

mhandler.sendmessagedelayed(message.obtain(mhandler, tick_what), 1000);

} else {

mhandler.removemessages(tick_what);

}

mrunning = running;

}

}

private handler mhandler = new handler() {

public void handlemessage(message m) {

if (mrunning) {

updatetext(systemclock.elapsedrealtime());

dispatchchronometertick();

sendmessagedelayed(message.obtain(this, tick_what), 1000);

}

}

};

用updatetext()方法设置时间显示。 至于计时循环机制,和方法二相同,同样是调用了handler的handmessagedelayed方法。

(3)运行结果:

02e496f784f1fae494af197d21682f54.png

注意:最后说一个关于chronometer类的常见问题,看到很多人都问用chronometer类如何设置格式hh:mm:ss的时间。(如果您有此问题请继续看,没有问题请忽略)

问这个问题的童鞋先看一下官方文档的描述:

if the format string is null, or if you never call setformat(), the chronometer will simply display the timer value in "mm:ss" or "h:mm:ss" form.

也就是说默认情况下,使用的格式是"mm:ss" 或者 "h:mm:ss", 然后有童鞋又会问:那到底是"mm:ss" 还是 "h:mm:ss"。我们先看一下源码:

updatetext():

private synchronized void updatetext(long now) {

long seconds = now - mbase;

seconds /= 1000;

string text = dateutils.formatelapsedtime(mrecycle, seconds);

if (mformat != null) {

locale loc = locale.getdefault();

if (mformatter == null || !loc.equals(mformatterlocale)) {

mformatterlocale = loc;

mformatter = new formatter(mformatbuilder, loc);

}

mformatbuilder.setlength(0);

mformatterargs[0] = text;

try {

mformatter.format(mformat, mformatterargs);

text = mformatbuilder.tostring();

} catch (illegalformatexception ex) {

if (!mlogged) {

log.w(tag, "illegal format string: " + mformat);

mlogged = true;

}

}

}

settext(text);

}

调用了dateutils.formatelapsedtime, 看一下dateutils.formatelapsedtime里面都有啥:

public static string formatelapsedtime(stringbuilder recycle, long elapsedseconds) {

formatter f = new formatter(sb, locale.getdefault());

initformatstrings();

if (hours > 0) {

return f.format(selapsedformathmmss, hours, minutes, seconds).tostring();

} else {

return f.format(selapsedformatmmss, minutes, seconds).tostring();

}

}

代码较多,我就挑重点截取了,仔细看看上面哪个if(){}else{}语句,你肯定就恍然大悟了吧?

为了我们理论的正确性,将方法三 activity中的代码稍作修改:

chronometer.setbase(-18000000);

运行结果如下:

be18b8eb0d85b3de57a8d6fdae93e202.png

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持萬仟网。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值