048android初级篇之定时器Timer和TimerTask的详细使用

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

  1. TimerTask 只能被schedule一次,然后被cancel后,就不能再被schedule调用,否则会抛异常。 java.lang.IllegalStateException: TimerTask is canceled

那么如果需要反复注册任务的话,只好重建TimerTask。

Timer

  1. 每一个Timer仅对应唯一一个线程。
  2. Timer不保证任务执行的十分精确。schedule函数尽量让每一次间隔精准,而scheduleAtFixedRate则是,尽量在算好的时间执行。
  3. 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();
            }
        });
    }
}

参考链接

  1. 032android初级篇之Timer的使用及获取栈顶包名
  2. JDK中的Timer和TimerTask详解
  3. Class Timer

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java相关

设计模式之—适配器模式

将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够一起工作。

12420
来自专栏IT杂记

TThreadedSelectorServer介绍及Direct Memory OOM分析

一、TThreadedSelectorServer线程模型: 该服务会启动1个AcceptThread, 2个SelectorThread(默认为2个,可设置)...

29880
来自专栏Android随笔

LeakCanary笔记

RefWatcher 的代理类。通过注册 ActivityLifecycleCallbacks 回调,当 Activity 调用 onDestroy() 时进行...

10120
来自专栏封碎

Android获取其他包的Context实例然后干坏事 博客分类: Android AndroidSecurityOSCC++

      Android中有Context的概念,想必大家都知道。Context可以做很多事情,打开activity、发送广播、打开本包下文件夹和数据库、获取...

26030
来自专栏上善若水

045android初级篇之android中一些路径的获取方法(如SD卡)

内部存储路径/data/data/youPackageName/,在程序安装的时候创建,在卸载的时候被删除。

18630
来自专栏xingoo, 一个梦想做发明家的程序员

【插件开发】—— 14 Site is incorrect!编辑器启动报错!

最近在弄编辑器的时候出现了一个十分尴尬的错误!这里收录一下:   BUG如下图所示: ?   目测堆栈,与自己开发的代码无关。完全是Eclipse自己初始...

24060
来自专栏androidBlog

二次封装图片第三方框架——简单工厂模式的运用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/de...

12620
来自专栏jianhuicode

学问Chat UI(2)

前言 上文讲了下要去做哪些事,重点分析了融云Sdk中RongExtension这个扩展控件,本文来学习下同样是融云Sdk中的AutoRefreshListVie...

23860
来自专栏java工会

Spring Bean的生命周期管理

14940
来自专栏大内老A

ASP.NET MVC的View是如何被呈现出来的?[设计篇]

在前面的四篇文章中,我们介绍了各种ActionResult以及相关的请求响应机制,但是与“View的呈现”相关的ActionResult是ViewResult。...

38680

扫码关注云+社区

领取腾讯云代金券