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

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

目录:

1、借助Timer实现

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

3、借助布局Chronometer

1、借助Timer实现

(1) 布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical" >

  <TextView
   android:id="@+id/timerView"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_gravity="center_horizontal"
   android:textSize="60sp" />

 </LinearLayout>

布局文件很简单,就是一个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)运行结果:

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) 布局文件

 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical" >

   <Chronometer
     android:id="@+id/chronometer"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_gravity="center_horizontal"
     android:textSize="60sp" />

</LinearLayout>

布局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)运行结果:

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

运行结果如下:

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

(0)

相关推荐

  • Android时分秒计时器的两种实现方法

    可能我们在开发中会时常用到计时器这玩意儿,比如在录像的时候,我们可能需要在右上角显示一个计时器.这个东西其实实现起来非常简单. 只需要用一个控件Chronometer,是的,就这么简单,我都不好意思讲述一下了. <Chronometer android:layout_width="wrap_content" android:layout_height="wrap_content" android:format="%s" android:id

  • Android编程之计时器Chronometer简单示例

    本文实例讲述了Android计时器Chronometer.分享给大家供大家参考,具体如下: Android中Chronometer控件继承自TextView,这个组件可以用1秒的时间间隔进行计时,并显示出计时结果.就是我们常说的计时器工具. public class ChronometerActivity extends Activity implements OnClickListener { private Chronometer mChronometer; private Button s

  • android开发教程之间隔执行程序(android计时器)

    下面是每隔一段时间就执行某个操作,直到关闭定时操作: 复制代码 代码如下: final Handler handler = new Handler();     Runnable runnable = new Runnable(){         @Override         public void run() {             // TODO Auto-generated method stub             // 在此处添加执行的代码             ha

  • android之计时器(Chronometer)的使用以及常用的方法

    在Android的SDK中,为我们提供了一个计时器,这个计时器称为Chronometer,我们可以成它为Android的一个组件,同时它也具备自己独有的方法.下面我们举例介绍下这个计时器的使用以及常用的方法. 跟其他UI组件一样,当我们要使用它的时候,在布局文件中对应的位置声明定义计时器的位置与属性. 复制代码 代码如下: <Chronometer android:id="@+id/chronometer" android:layout_width="wrap_cont

  • 学习使用Android Chronometer计时器

    本文实例为大家分享了Android Chronometer计时器基本使用方法,供大家参考,具体内容如下 在默认情况下,Chronometer组件只输出MM:SS或H:MM:SS的时间格式.例如,当计时到1分20秒时,Chronometer组件会显示01:20.如果想改变显示的信息内容,可以使用Chronometer类的setFormat方法.该方法需要一个String变量,并使用"%s"表示计时信息.例如,使用setFormat("计时信息:%s")设置显示信息,C

  • Android Chronometer控件实现计时器函数详解

    本文为大家演示了如何使用Chronometer控件实现Android计时器的实例. 先贴上最终的实现效果图: Android计时器实现思路 使用Chronometer控件实现计器的操作.通过设置setBase(long base)来设置初始时间,然后为其添加一个 setOnChronometerTickListener(Chronometer.OnChronometerTickListener l)事件来判断时间是否到了,然后再调用其stop()方法实现停止计时. Android计时器实现代码

  • android计时器,时间计算器的实现方法

    需求:默认为"00:00:00",点击开始按钮时清零后开始计时,出现如10:28:34.点击停止的时候停止计时.问题:使用Calendar DateFormat的方法,不设置时区获取到的小时是本地时区的(东八区的就是8),设置成GMT标准时区获取到的时间是12小时(12:00:00),设置24小时制无效.在开始时间加减各种小时都无效,而且计时只能到12小时就自动跳上去了,始终无法出现默认状态00:00:00开始计时的效果.尝试各种时间设置方法无效后只能自己写一个根据秒数转换时间格式字符

  • Android计时器控件Chronometer应用实例

    显示一个计时器开始计时,当计时器到达15s的时候,停止计时.此时页面多一个重置按钮,可再次进行计时. 页面布局 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout

  • Android 编程下的计时器代码

    同样,为了防止用户恶意的频繁发送激活码,应用中需要对用户发送激活码的时间间隔进行限制,这时就需要用到倒计时器了,大概流程是这样的:页面初始化的时候,按钮为可点击状态,用户在点击"发送激活码"后按钮变为不可点击状态,同时按钮上的文字变为倒计时状态,倒计时结束后,按钮变为可点击状态,文字变为"发送激活码".具体逻辑看下面的代码: 复制代码 代码如下: package cn.sunzn.countdown; import android.app.Activity;impo

  • Android计时器chronometer使用实例讲解

    在Android中,可以使用计时器来实现对时间的监测,这个类所实现的功能有开始计时,停止计时,重新计时,设置计 时模式,下面列出计时器方法的原型: long getBase();//返回基地的时间,由setBase(long)设置的 String getFormat(); //返回当前字符串格式,此格式是通过setFormat()实现的 void setBase(long base); //设置时间,计数定时器指定的值 void setFormat(String format); //设置显示的

随机推荐