目录:

1、借助Timer实现

2、调用handler.sendMessagedely(Message msg, long delayMillis)

3、借助布局Chronometer

1、借助Timer实现

(1) 布局文件

1

2 3 android:layout_width="match_parent"

4 android:layout_height="match_parent"

5 android:orientation="vertical" >

6

7

9 android:layout_width="wrap_content"

10 android:layout_height="wrap_content"

11 android:layout_gravity="center_horizontal"

12 android:textSize="60sp" />

13

14

chrono.xml

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

(2)Activity文件

1 public class MyChronometer extendsActivity {2 privateTextView timerView;3 private longbaseTimer;4

5 @Override6 protected voidonCreate(Bundle savedInstanceState) {7 setContentView(R.layout.chrono);8 MyChronometer.this.baseTimer =SystemClock.elapsedRealtime();9 timerView = (TextView) this.findViewById(R.id.timerView);10 final Handler startTimehandler = newHandler(){11 public voidhandleMessage(android.os.Message msg) {12 if (null !=timerView) {13 timerView.setText((String) msg.obj);14 }15 }16 };17 new Timer("开机计时器").scheduleAtFixedRate(newTimerTask() {18 @Override19 public voidrun() {20 int time = (int)((SystemClock.elapsedRealtime() - MyChronometer.this.baseTimer) / 1000);21 String hh = new DecimalFormat("00").format(time / 3600);22 String mm = new DecimalFormat("00").format(time % 3600 / 60);23 String ss = new DecimalFormat("00").format(time % 60);24 String timeFormat = new String(hh + ":" + mm + ":" +ss);25 Message msg = newMessage();26 msg.obj =timeFormat;27 startTimehandler.sendMessage(msg);28 }29

30 }, 0, 1000L);31 super.onCreate(savedInstanceState);32 }

MyChronometer.java

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

(3)运行结果:

2.调用handler.sendMessagedely(Message msg, long delayMillis)

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

(2)Activity文件

1 public class MyChronometer extendsActivity {2 privateTextView timerView;3 private longbaseTimer;4

5 @Override6 protected voidonCreate(Bundle savedInstanceState) {7 setContentView(R.layout.chrono);8 MyChronometer.this.baseTimer =SystemClock.elapsedRealtime();9 timerView = (TextView) this.findViewById(R.id.timerView);10 Handler myhandler = newHandler(){11 public voidhandleMessage(android.os.Message msg) {12 if (0 == MyChronometer.this.baseTimer) {13 MyChronometer.this.baseTimer =SystemClock.elapsedRealtime();14 }15

16 int time = (int)((SystemClock.elapsedRealtime() - MyChronometer.this.baseTimer) / 1000);17 String hh = new DecimalFormat("00").format(time / 3600);18 String mm = new DecimalFormat("00").format(time % 3600 / 60);19 String ss = new DecimalFormat("00").format(time % 60);20 if (null != MyChronometer.this.timerView) {21 timerView.setText(hh + ":" + mm + ":" +ss);22 }23 sendMessageDelayed(Message.obtain(this, 0x0), 1000);24 }25 };26 myhandler.sendMessageDelayed(Message.obtain(myhandler, 0x0), 1000);27 super.onCreate(savedInstanceState);28 }

MyChronometer

sendMessageDelayed (Message msg, long delayMillis):在 delayMillis/1000 秒后发送消息 msg。

在Handler 的 handleMessage()方法中调用sendMessageDelayed方法, 巧妙的实现了循环。需要注意的是,在Handler外要调用一次startTimehandler.sendMessageDelayed(Message.obtain(startTimehandler, 0x0), 1000);  以作为循环的入口。

3.借助布局Chronometer

(1) 布局文件

1 xml version="1.0" encoding="utf-8"?>

2

3 android:layout_width="match_parent"

4 android:layout_height="match_parent"

5 android:orientation="vertical" >

6

7

9 android:layout_width="wrap_content"

10 android:layout_height="wrap_content"

11 android:layout_gravity="center_horizontal"

12 android:textSize="60sp" />

13

14 LinearLayout>

chono.xml

布局Chronometer继承自TextView

(2)Activity文件

1 public class MyChronometer extendsActivity {2

3 Chronometer chronometer;4 @Override5 protected voidonCreate(Bundle savedInstanceState) {6 setContentView(R.layout.chrono);7 chronometer = (Chronometer) this.findViewById(R.id.chronometer);8 chronometer.setBase(SystemClock.elapsedRealtime());9 chronometer.start();10 super.onCreate(savedInstanceState);11 }12 }

MyChronometer.java

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

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

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

public void start() {

mStarted = true;

updateRunning();

}

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

1 private void updateRunning() {2 boolean running = mVisible && mStarted;3 if (running != mRunning) {4 if (running) {5 updateText(SystemClock.elapsedRealtime());6 dispatchChronometerTick();7 mHandler.sendMessageDelayed(Message.obtain(mHandler, TICK_WHAT), 1000);8 } else {9 mHandler.removeMessages(TICK_WHAT);10 }11 mRunning = running;12 }13 }14

15 private Handler mHandler = new Handler() {16 public void handleMessage(Message m) {17 if (mRunning) {18 updateText(SystemClock.elapsedRealtime());19 dispatchChronometerTick();20 sendMessageDelayed(Message.obtain(this, TICK_WHAT), 1000);21 }22 }23 };

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

(3)运行结果:

注意:最后说一个关于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():

1 private synchronized void updateText(longnow) {2 long seconds = now -mBase;3 seconds /= 1000;4 String text =DateUtils.formatElapsedTime(mRecycle, seconds);5

6 if (mFormat != null) {7 Locale loc =Locale.getDefault();8 if (mFormatter == null || !loc.equals(mFormatterLocale)) {9 mFormatterLocale =loc;10 mFormatter = newFormatter(mFormatBuilder, loc);11 }12 mFormatBuilder.setLength(0);13 mFormatterArgs[0] =text;14 try{15 mFormatter.format(mFormat, mFormatterArgs);16 text =mFormatBuilder.toString();17 } catch(IllegalFormatException ex) {18 if (!mLogged) {19 Log.w(TAG, "Illegal format string: " +mFormat);20 mLogged = true;21 }22 }23 }24 setText(text);25 }

updateText(long)

调用了DateUtils.formatElapsedTime, 看一下DateUtils.formatElapsedTime里面都有啥:

1 public static String formatElapsedTime(StringBuilder recycle, longelapsedSeconds) {2 Formatter f = newFormatter(sb, Locale.getDefault());3 initFormatStrings();4 if (hours > 0) {5 returnf.format(sElapsedFormatHMMSS, hours, minutes, seconds).toString();6 } else{7 returnf.format(sElapsedFormatMMSS, minutes, seconds).toString();8 }9 }

formatElapsedTime

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

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

chronometer.setBase(-18000000);

运行结果如下:

(最近工作中遇到相关代码异常,就学习了一下, 如果有什么错误,希望大家多多探讨和指教)

android time计时器,android 计时器的三种实现(Chronometer、Timer、handler)相关推荐

  1. android获取自定义属性,android 自定义控件中获取属性的三种方式(转)

    第一种方法,直接设置属性值,通过attrs.getAttributeResourceValue拿到这个属性值. (1)在xml文件中设置属性值 android:layout_width="f ...

  2. Android数据存储和读取的三种方法

    Android数据存储和读取的三种方法 一.文件存储 二.Context存储 三.SharedPreferences存储 一.文件存储 1.利用文件进行数据的存储 public static bool ...

  3. Android开发中完全退出程序的三种方法

    Android程序有很多Activity,比如说主窗口A,调用了子窗口B,在B中如何关闭整个Android应用程序呢? 这里给大家三种比较简单的方法实现. 首先要说明在B中直接使用finish(),接 ...

  4. android音频开发6,Android 音视频开发(一) : 通过三种方式绘制图片

    想要逐步入门音视频开发,就需要一步步的去学习整理,并积累.本文是音视频开发积累的第一篇. 对应的要学习的内容是:在 Android 平台绘制一张图片,使用至少 3 种不同的 API,ImageView ...

  5. android 编译宏,android 添加全局变量宏开关的三种方式

    开发的时候,我们经常会有这样的一种需求: 在什么位置(如db)保存一个变量,可以跨应用的读写此值. system.prop 我们可以在system.prop中定义一个宏开关,可以很好的实现此目的. 此 ...

  6. Android Studio导入外部资源的三种方式

    在Android Studio打开导入外资源的路径:File->Project Structure- 第一步:选择Dependencies 第二步:选择要添加依赖的modules 第三步:为mo ...

  7. Android Bluetooth打开和关闭的三种方式(很详细)

    转载:http://www.ifeegoo.com/android-turn-on-and-turn-off-bluetooth.html 摘要:Android 中打开和关闭 Bluetooth 的代 ...

  8. Android屏幕保持常亮的三种方法

    一.界面布局文件顶层添加keepScreenOn属性 android:keepScreenOn="true" 二.Window中设置flag getWindow().addFlag ...

  9. android唤醒音乐播放器,android调用音乐播放器,三种方

    小弟想请问一下.怎样在自己写的程序中调用系统的音乐播放器呢. 我在google上搜索了.主要是有两种方法,可是都不是我想要的. 第一种是.使用mp3音乐文件的uri.和intent,进行调用.可是这样 ...

  10. android 加阴影,Android设置控件阴影的三种方式

    释放双眼,带上耳机,听听看~! 第一种方式:elevation View的大小位置都是通过x,y确定的,而现在有了z轴的概念,而这个z值就是View的高度(elevation),而高度决定了阴影(sh ...

最新文章

  1. WebSocket的故事(六)—— Springboot中,实现更灵活的WebSocket
  2. 机器狗常州巡逻防疫,喊话“不扎堆不聚集”,网友:给孩子安个狗头吧
  3. 读《Oracle DBA工作笔记》知识点-获取创建语句
  4. 启明云端分享|ESP32-S3 Smartconfig一键配网
  5. java的set接口_Java集合-Set接口
  6. matlab求滤波器的冲激响应,在TMS320C5410上用MATLAB实现有限冲激响应滤波器
  7. 人工智能AI实战100讲(四)-基于深度学习的图像增强综述
  8. 好东西仿Vista窗体
  9. 大数据、人工智能如何融合?来自微软、阿里、滴滴、科大讯飞等的 120 多位专家要用 3 天为你解答!
  10. 103.二叉树的锯齿形层次遍历:DFS解法
  11. lpop 原子_从夸克到原子,到元素周期表
  12. 《计算机组成原理》唐朔飞第三版知识点总结
  13. cass有坐标文件生成里程文件_请问在CASS7.0中怎样生成坐标文件和里程文件,请尽量详细...
  14. ClickHouse磁盘清理
  15. requests 职友集招聘信息爬虫
  16. mapgis 转换为CAD格式图形 显示不出来的处理
  17. 【智能零售】解读双11后的新零售趋势
  18. c语言指针一览第一部分(新手向)
  19. 动漫培训学费一般多少钱
  20. 【Android】手机远程登录Windows服务器(使用Rd Client)

热门文章

  1. html5页面头部代码,HTML5标签:header元素的使用方法及作用
  2. opencv-之求直线的斜率
  3. matlab gz,MATLAB之single函数
  4. nltk系列:Lemmatisation和Stemming(NLTK pos_tag word_tokenize)
  5. 微信h5界面隐藏刷新功能_隐藏微信H5页面下拉出现的网址
  6. 免费在线语音识别成文字
  7. TARA-威胁建模方案3
  8. PushService开发分享
  9. excel输入 正在计算机,在Excel中输入内容后如何自动填写日期和时间
  10. 【C#】基础篇(3) C#实现串口助手,解决中文乱码