Timer是jdk中提供的一个定时器工具,使用的时候会在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次。
TimerTask是一个实现了Runnable接口的抽象类,代表一个可以被Timer执行的任务,需要重载run()方法,在其中实现自己的功能。
Timer 类API接口
构造函数
1. Timer()
Creates a new timer.
2. Timer(boolean isDaemon)
Creates a new timer whose associated thread may be specified to run as a daemon.
3. Timer(String name)
Creates a new timer whose associated thread has the specified name.
4. Timer(String name, boolean isDaemon)
Creates a new timer whose associated thread has the specified name, and may be specified to run as a daemon.
文中有提到
daemon Thread
daemon Thread可以翻译为守护进程,不过跟linux系统中的守护系统完全是两码事哦。
daemon是相于user线程而言的,可以理解为一种运行在后台的服务线程,比如时钟处理线程、idle线程、垃圾回收线程等都是daemon线程。
daemon线程的主要特点就是"比较次要",程序中如果所有的user线程都结束了,那这个程序本身就结束了,不管daemon是否结束。而user线程就不是这样,只要还有一个user线程存在,程序就不会退出。
name
这个没有发现有什么用。
其他函数
1. void cancel()
终止timer,丢弃所有任务的调度
Terminates this timer, discarding any currently scheduled tasks.
2. int purge()
Removes all cancelled tasks from this timer's task queue.
终止所有被取消的任务。
3. void schedule(TimerTask task, Date time)
Schedules the specified task for execution at the specified time.
在指定的时间,运行此任务。
4. void schedule(TimerTask task, Date firstTime, long period)
Schedules the specified task for repeated fixed-delay execution, beginning at the specified time.
在指定的时间Date firstTime运行此任务,之后每间隔long period时间运行一次。
5. void schedule(TimerTask task, long delay)
Schedules the specified task for execution after the specified delay.
6. void schedule(TimerTask task, long delay, long period)
Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay.
7. void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
Schedules the specified task for repeated fixed-rate execution, beginning at the specified time.
8. void scheduleAtFixedRate(TimerTask task, long delay, long period)
Schedules the specified task for repeated fixed-rate execution, beginning after the specified delay.
schedule和scheduleAtFixedRate的差异
这两个方法都是任务调度方法,他们之间区别是,schedule会保证任务的间隔是按照定义的period参数严格执行的,如果某一次调度时间比较长,那么后面的时间会顺延,保证调度间隔都是period,而scheduleAtFixedRate是严格按照调度时间来的,如果某次调度时间太长了,那么会通过缩短间隔的方式保证下一次调度在预定时间执行。举个栗子:你每个3秒调度一次,那么正常就是0,3,6,9s这样的时间,如果第二次调度花了2s的时间,如果是schedule,就会变成0,3+2,8,11这样的时间,保证间隔,而scheduleAtFixedRate就会变成0,3+2,6,9,压缩间隔,保证调度时间。
继承自class java.lang.Object的函数
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
TimerTask
A task that can be scheduled for one-time or repeated execution by a Timer.
1. protected TimerTask()
Creates a new timer task.
2. boolean cancel()
Cancels this timer task.
3. abstract void run()
The action to be performed by this timer task.
4. long scheduledExecutionTime()
Returns the scheduled execution time of the most recent actual execution of this task.
??返回下一次执行的时间 这一点不确认,运行测试代码,也不支持此解释,知道的同学指导下哈
总结
TimerTask
-
TimerTask 只能被schedule一次,然后被cancel后,就不能再被schedule调用,否则会抛异常。
java.lang.IllegalStateException: TimerTask is canceled
那么如果需要反复注册任务的话,只好重建TimerTask。
Timer
- 每一个Timer仅对应唯一一个线程。
- Timer不保证任务执行的十分精确。schedule函数尽量让每一次间隔精准,而scheduleAtFixedRate则是,尽量在算好的时间执行。
- Timer类的是线程安全的。
测试代码
/**
* Created by Frank on 2016/8/23.
*/
public class TestTimerActivity extends Activity {
private final String TAG ="TestTimerActivity";
private TextView textviewCounter;
private EditText editer;
private Button mButtonStart;
private Button mButtonStop;
int mCounter =0;
int mTime =1000;
Timer mTimer;
TimerTask mTimerTask;
public final int CODE_REFRESH = 1;
Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case CODE_REFRESH:
textviewCounter.setText(""+mCounter++);
break;
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.test_timer);
mTimer = new Timer();
mTimerTask = new TimerTask() {
@Override
public void run() {
if(textviewCounter!=null){
Message msg= mHandler.obtainMessage();
msg.what = CODE_REFRESH;
mHandler.sendMessage(msg);
}
}
};
mButtonStart =(Button) findViewById(R.id.start);
mButtonStop =(Button) findViewById(R.id.stop);
textviewCounter =(TextView) findViewById(R.id.textview_counter);
editer =(EditText) findViewById(R.id.edit_text);
mButtonStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mTimerTask !=null){
mTimerTask.cancel();
Log.e(TAG,"time = "+mTimerTask.scheduledExecutionTime());
}
mTimer.purge();
mTimerTask = new TimerTask() {
@Override
public void run() {
if(textviewCounter!=null){
Message msg= mHandler.obtainMessage();
msg.what = CODE_REFRESH;
mHandler.sendMessage(msg);
}
}
};
//mTime = Integer.parseInt(editer.getText().toString());
mTime = 800;
mTimer.schedule(mTimerTask,mTime,mTime);
Log.e(TAG,"2time = "+mTimerTask.scheduledExecutionTime());
}
});
mButtonStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mTimerTask !=null){
mTimerTask.cancel();
}
mTimer.purge();
}
});
}
}
参考链接
- 032android初级篇之Timer的使用及获取栈顶包名
- JDK中的Timer和TimerTask详解
- Class Timer