android time计时器,android 计时器的三种实现(Chronometer、Timer、handler)
目录:
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)相关推荐
- android获取自定义属性,android 自定义控件中获取属性的三种方式(转)
第一种方法,直接设置属性值,通过attrs.getAttributeResourceValue拿到这个属性值. (1)在xml文件中设置属性值 android:layout_width="f ...
- Android数据存储和读取的三种方法
Android数据存储和读取的三种方法 一.文件存储 二.Context存储 三.SharedPreferences存储 一.文件存储 1.利用文件进行数据的存储 public static bool ...
- Android开发中完全退出程序的三种方法
Android程序有很多Activity,比如说主窗口A,调用了子窗口B,在B中如何关闭整个Android应用程序呢? 这里给大家三种比较简单的方法实现. 首先要说明在B中直接使用finish(),接 ...
- android音频开发6,Android 音视频开发(一) : 通过三种方式绘制图片
想要逐步入门音视频开发,就需要一步步的去学习整理,并积累.本文是音视频开发积累的第一篇. 对应的要学习的内容是:在 Android 平台绘制一张图片,使用至少 3 种不同的 API,ImageView ...
- android 编译宏,android 添加全局变量宏开关的三种方式
开发的时候,我们经常会有这样的一种需求: 在什么位置(如db)保存一个变量,可以跨应用的读写此值. system.prop 我们可以在system.prop中定义一个宏开关,可以很好的实现此目的. 此 ...
- Android Studio导入外部资源的三种方式
在Android Studio打开导入外资源的路径:File->Project Structure- 第一步:选择Dependencies 第二步:选择要添加依赖的modules 第三步:为mo ...
- Android Bluetooth打开和关闭的三种方式(很详细)
转载:http://www.ifeegoo.com/android-turn-on-and-turn-off-bluetooth.html 摘要:Android 中打开和关闭 Bluetooth 的代 ...
- Android屏幕保持常亮的三种方法
一.界面布局文件顶层添加keepScreenOn属性 android:keepScreenOn="true" 二.Window中设置flag getWindow().addFlag ...
- android唤醒音乐播放器,android调用音乐播放器,三种方
小弟想请问一下.怎样在自己写的程序中调用系统的音乐播放器呢. 我在google上搜索了.主要是有两种方法,可是都不是我想要的. 第一种是.使用mp3音乐文件的uri.和intent,进行调用.可是这样 ...
- android 加阴影,Android设置控件阴影的三种方式
释放双眼,带上耳机,听听看~! 第一种方式:elevation View的大小位置都是通过x,y确定的,而现在有了z轴的概念,而这个z值就是View的高度(elevation),而高度决定了阴影(sh ...
最新文章
- WebSocket的故事(六)—— Springboot中,实现更灵活的WebSocket
- 机器狗常州巡逻防疫,喊话“不扎堆不聚集”,网友:给孩子安个狗头吧
- 读《Oracle DBA工作笔记》知识点-获取创建语句
- 启明云端分享|ESP32-S3 Smartconfig一键配网
- java的set接口_Java集合-Set接口
- matlab求滤波器的冲激响应,在TMS320C5410上用MATLAB实现有限冲激响应滤波器
- 人工智能AI实战100讲(四)-基于深度学习的图像增强综述
- 好东西仿Vista窗体
- 大数据、人工智能如何融合?来自微软、阿里、滴滴、科大讯飞等的 120 多位专家要用 3 天为你解答!
- 103.二叉树的锯齿形层次遍历:DFS解法
- lpop 原子_从夸克到原子,到元素周期表
- 《计算机组成原理》唐朔飞第三版知识点总结
- cass有坐标文件生成里程文件_请问在CASS7.0中怎样生成坐标文件和里程文件,请尽量详细...
- ClickHouse磁盘清理
- requests 职友集招聘信息爬虫
- mapgis 转换为CAD格式图形 显示不出来的处理
- 【智能零售】解读双11后的新零售趋势
- c语言指针一览第一部分(新手向)
- 动漫培训学费一般多少钱
- 【Android】手机远程登录Windows服务器(使用Rd Client)
热门文章
- html5页面头部代码,HTML5标签:header元素的使用方法及作用
- opencv-之求直线的斜率
- matlab gz,MATLAB之single函数
- nltk系列:Lemmatisation和Stemming(NLTK pos_tag word_tokenize)
- 微信h5界面隐藏刷新功能_隐藏微信H5页面下拉出现的网址
- 免费在线语音识别成文字
- TARA-威胁建模方案3
- PushService开发分享
- excel输入 正在计算机,在Excel中输入内容后如何自动填写日期和时间
- 【C#】基础篇(3) C#实现串口助手,解决中文乱码