第一種:Timer和TimerTask結(jié)合
在java.util.Timer
的源碼中看到Timer的構(gòu)造方法
public Timer(String name) {
thread.setName(name);
thread.start();
}
public Timer(boolean isDaemon) {
this("Timer-" + serialNumber(), isDaemon);
}
public Timer(String name, boolean isDaemon) {
thread.setName(name);
thread.setDaemon(isDaemon);
thread.start();
}
關(guān)于thread.setDaemon(isDaemon);
Java中線程分為兩種類型:用戶線程和守護(hù)線程吹由。
通過(guò)Thread.setDaemon(false)設(shè)置為用戶線程讹躯;通過(guò)Thread.setDaemon(true)設(shè)置為守護(hù)線程苍日。如果不設(shè)置次屬性,默認(rèn)為用戶線程。
用戶線程和守護(hù)線程的區(qū)別:
- 主線程結(jié)束后用戶線程還會(huì)繼續(xù)運(yùn)行,JVM存活;主線程結(jié)束后守護(hù)線程和JVM的狀態(tài)又下面第2條確定。
- 如果沒(méi)有用戶線程悼瓮,都是守護(hù)線程,那么JVM結(jié)束(隨之而來(lái)的是所有的一切煙消云散艰猬,包括所有的守護(hù)線程)横堡。
我們要用到的schedule()方法如下:
public void schedule(TimerTask task, long delay, long period) {
if (delay < 0)
throw new IllegalArgumentException("Negative delay.");
if (period <= 0)
throw new IllegalArgumentException("Non-positive period.");
sched(task, System.currentTimeMillis()+delay, -period);
}
- 第一個(gè)參數(shù)task就是TimerTask對(duì)象,最終要實(shí)現(xiàn)的就是task的run()方法;
- 第二個(gè)參數(shù)delay類型為long,表示延時(shí)多久后開(kāi)始執(zhí)行task;
- 第三個(gè)參數(shù)period類型為long,表示多久重復(fù)一次run()方法;
另外Timer調(diào)用task還有以下方法
//time為Date類型:在指定時(shí)間執(zhí)行一次。
timer.schedule(task, time);
//firstTime為Date類型,period為long冠桃,表示從firstTime時(shí)刻開(kāi)始翅萤,每隔period毫秒執(zhí)行一次。
timer.schedule(task, firstTime,period);
//delay 為long類型:從現(xiàn)在起過(guò)delay毫秒執(zhí)行一次腊满。
timer.schedule(task, delay);
//delay為long,period為long:從現(xiàn)在起過(guò)delay毫秒以后套么,每隔period毫秒執(zhí)行一次。
timer.schedule(task, delay,period);
使用:
兩秒鐘之后timer_tv_1開(kāi)始顯示當(dāng)前時(shí)間并每一秒更新一次
private void Timer1(){
Timer timer=new Timer();
TimerTask task=new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
timer_tv_1.setText("Timer1-->"+getSystemTime());
}
});
}
};
timer.schedule(task,2000,1000);
}
別忘了在onDestroy()中
if (timer1 != null) {
timer1.cancel();
}
第二種.Handler自帶的postDelayed(Runnable r, long delayMillis)方法
Handler handler2 = new Handler();
Runnable runnable2 = new Runnable() {
@Override
public void run() {
handler2.postDelayed(this, 1000);
timer_tv_2.setText("Timer2-->" + getSystemTime());
}
};
private void Timer2() {
handler2.postDelayed(runnable2, 1000);
}
Timer2()方法中的
handler2.postDelayed(runnable2, 1000);
和runnable2的run()中的handler2.postDelayed(this, 1000);
都為延時(shí)一秒鐘執(zhí)行runnable2,
Timer2()中postDelayed為入口,handler2中的postDelayed讓自己陷入死循環(huán),這種方法要記得在onDestroy()中
handler2.removeCallbacks(runnable2);
第三種:最神經(jīng)病的寫(xiě)法(適合簡(jiǎn)單的UI變化)
Handler handler3 = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 0) {
timer_tv_3.setText("Timer3-->" + getSystemTime());
this.sendEmptyMessageDelayed(0, 1000);
}
}
};
private void Timer3() {
handler3.sendEmptyMessageDelayed(0, 1000);
}
第四種:利用Thread.sleep(time);
Handler handler4 = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 0) {
timer_tv_4.setText("Timer4-->" + getSystemTime());
}
}
};
public class Timer4Thread implements Runnable {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
Message msg = new Message();
msg.what = 0;
handler4.sendMessage(msg);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void Timer4() {
new Thread(new Timer4Thread()).start();
}
原理就是讓實(shí)現(xiàn)了Runnable接口的Timer4Thread陷入死循環(huán),利用
Thread.sleep(1000);
達(dá)到定時(shí)的目的.
關(guān)鍵的一句是while (true) {}
最后附上效果圖和獲取時(shí)間代碼
ezgif-3-cba9691b5d.gif
private String getSystemTime() {
return transferLongToDate("yyyy-dd-MM HH:mm:ss", System.currentTimeMillis()) + "";
}
/**
* 把毫秒轉(zhuǎn)化成日期
*
* @param dateFormat(日期格式碳蛋,例如:MM/ dd/yyyy HH:mm:ss)
* @param millSec(毫秒數(shù))
* @return
*/
public static String transferLongToDate(String dateFormat, Long millSec) {
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
Date date = new Date(millSec);
return sdf.format(date);
}