国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android計時器的三種實現方式

2020-02-21 17:28:03
字體:
來源:轉載
供稿:網友

我們在開發過程中,隨時都會使用到計時器,像錄像都需要有一個顯示計時器,其實實現這些東西對于程序員來說很簡單,下文是武林技術頻道小編為大家帶來的Android計時器的三種實現方式,請大家一起去看看吧。

本文實例為大家分享了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);

運行結果如下:

以上就是關于Android計時器的三種實現方式,介紹的已經很詳細了,如果你還想了解其他知識,你可以來武林技術頻道詳加學習和了解。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阜康市| 竹溪县| 孝感市| 奉化市| 永丰县| 龙南县| 顺义区| 延吉市| 海原县| 吉隆县| 临沧市| 白银市| 弥渡县| 仪征市| 黄大仙区| 滕州市| 永年县| 永城市| 常熟市| 南雄市| 赤城县| 衡南县| 临洮县| 策勒县| 叶城县| 马龙县| 大渡口区| 南川市| 鄄城县| 离岛区| 湖南省| 湟源县| 大埔区| 安宁市| 贵港市| 中方县| 房产| 鄢陵县| 康马县| 乌鲁木齐县| 浑源县|