Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了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://scheR_886_11845@as.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);
       }
       
     },1000L);
     super.onCreate(savedInstanceStatE);
   }

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

(3)运行结果:

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

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,1000);
     super.onCreate(savedInstanceStatE);
   }

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

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

3.借助布局Chronometer

(1) 布局文件

 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://scheR_886_11845@as.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,1000);
       }
     }
   };

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

(3)运行结果:

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

注意:最后说一个关于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,seconds).toString();
     }
   }

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

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

chronometer.setBase(-18000000);

运行结果如下:

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

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

大佬总结

以上是大佬教程为你收集整理的Android计时器的三种实现方式(Chronometer、Timer、handler)全部内容,希望文章能够帮你解决Android计时器的三种实现方式(Chronometer、Timer、handler)所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。