android之几种定时器实现

1,193次阅读
没有评论

在android中,经常用到的定时器主要有以下几种实现: 
一、采用Handler与线程的sleep(long )方法 
二、采用Handler的postDelayed(Runnable, long) 方法 
三、采用Handler与timer及TimerTask结合的方法。 
详细介绍: 
一、采用Handle与线程的sleep(long )方法 
Handler主要用来处理接受到的消息。这只是最主要的方法,当然Handler里还有其他的方法供实现,有兴趣的可以去查API,这里不过多解释。 
1、定义一个Handler类,用于处理接受到的Message. 

 Handler handler = new Handler() { 
        public void handleMessage(Message msg) { 
//要做的事情 
            super.handleMessage(msg); 
        } 
    }; 

2、新建一个实现Runnable接口的线程类。如下: 

    public class MyThread implements Runnable{ 
        @Override 
        public void run() { 
// TODO Auto-generated method stub 
            while (true) { 
                try { 
                    Thread.sleep(10000);//线程暂停10秒,单位毫秒 
                    Message message=new Message(); 
                    message.what=1; 
                    handler.sendMessage(message);//发送消息 
                } catch (InterruptedException e) { 
// TODO Auto-generated catch block 
                    e.printStackTrace(); 
                } 
            } 
        } 
    } 

3、在需要启动线程的地方加入下面语句: 

new Thread(new MyThread()).start(); 

4、启动线程后,线程每10s发送一次消息。 
二、采用Handler的postDelayed(Runnable, long) 方法 
这个实现比较简单一些: 
1、

 Handler handler=new Handler(); 
    Runnable runnable=new Runnable(){ 
        @Override 
        public void run() { 
// TODO Auto-generated method stub 
//要做的事情 
            handler.postDelayed(this, 2000); 
        } 
    }; 

2、启动计时器: 

handler.postDelayed(runnable, 2000);//每两秒执行一次runnable. 

3、停止计时器: 

handler.removeCallbacks(runnable); 

三、采用Handler与timer及TimerTask结合的方法。 
1、定义定时器、定时器任务及Handler句柄 

 private final Timer timer = new Timer(); 
    private TimerTask task; 
    Handler handler = new Handler() { 
        @Override 
        public void handleMessage(Message msg) { 
// TODO Auto-generated method stub 
//要做的事情 
            super.handleMessage(msg); 
        }
 
    }; 

2、初始化计时器任务。 

 task = new TimerTask() { 
        @Override 
        public void run() { 
// TODO Auto-generated method stub 
            Message message = new Message(); 
            message.what = 1; 
            handler.sendMessage(message); 
        } 
    };  

3、启动定时器 

timer.schedule(task, 2000, 2000); 

分析:

1、定义定时器、定时器任务及Handler句柄 

定时器任务(TimerTask)顾名思义,就是说当定时器到达指定的时间时要做的工作,这里是想Handler发送一个消息,由Handler类进行处理。

2、初始化计时器任务。 

java.util.Timer.schedule(TimerTask task, long delay):这个方法是说,dalay/1000秒后执行task.只执行一次。
 java.util.Timer.schedule(TimerTask task, long delay, long period):这个方法是说,delay/1000秒后执行task,然后进过period/1000秒再次执行task,这个用于循环任务,执行无数次,当然,你可以用timer.cancel();取消计时器的执行。

3、启动定时器 

然后是有关 Java.util.Timer 和 AlarmService的
Android上常用的定时器有两种,一种是Java.util.Timer,一种就是系统的AlarmService了。
实验1:使用Java.util.Timer。 
在onStart()创创建Timer,每5秒更新一次计数器,并启动。  mTimer = new Timer();          

mTimer = new Timer();
mTimer.schedule(new TimerTask() {
@Override
public void run() {
++mCount;
mHandler.sendEmptyMessage(0);        
}   
    }, 5*1000, 5*1000);  

mTimer = new Timer();                
        mTimer.schedule(new TimerTask() {                        
                    @Override 
                    public void run() { 
                            ++mCount; 
                            mHandler.sendEmptyMessage(0);                               
                     } 
            }, 5*1000, 5*1000);    

  

当连接USB线进行调试时,会发现一切工作正常,每5秒更新一次界面,即使是按下电源键,仍然会5秒触发一次。 
当拔掉USB线,按下电源键关闭屏幕后,过一段时间再打开,发现定时器明显没有继续计数,停留在了关闭电源键时的数字。

实验2:使用AlarmService: 
(1)通过AlarmService每个5秒发送一个广播,setRepeating时的类型为AlarmManager.ELAPSED_REALTIME。 

AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);   am.setRepeating(AlarmManager.ELAPSED_REALTIME, firstTime, 5*1000, sender); 
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE); am.setRepeating(AlarmManager.ELAPSED_REALTIME, firstTime, 5*1000, sender);

拔掉USB线,按下电源键,过一段时间再次打开屏幕,发现定时器没有继续计数。 
(2)setRepeating是的类型设置为AlarmManager.ELAPSED_REALTIME_WAKEUP 

AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);   am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, 5*1000, sender); 
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE); am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, 5*1000, sender);

拔掉USB线,按下电源键,过一点时间再次打开屏幕,发现定时器一直在计数。

如此看来,使用WAKEUP才能保证自己想要的定时器一直工作,但是肯定会引起耗电量的增加。

最后是有关schedule和scheduleAtFixedRate区别

schedule和scheduleAtFixedRate 区别:

(1) 2个参数的schedule在制定任务计划时,如果指定的计划执行时间scheduledExecutionTime<= systemCurrentTime,则task会被立即执行。scheduledExecutionTime不会因为某一个task的过度执行而改变。
 (2) 3个参数的schedule在制定反复执行一个task的计划时,每一次执行这个task的计划执行时间随着前一次的实际执行时间而变,也就是 scheduledExecutionTime(第n+1次)=realExecutionTime(第n次)+periodTime。也就是说如果第n 次执行task时,由于某种原因这次执行时间过长,执行完后的systemCurrentTime>= scheduledExecutionTime(第n+1次),则此时不做时隔等待,立即执行第n+1次task,而接下来的第n+2次task的 scheduledExecutionTime(第n+2次)就随着变成了realExecutionTime(第n+1次)+periodTime。说白了,这个方法更注重保持间隔时间的稳定。
 (3)3个参数的scheduleAtFixedRate在制定反复执行一个task的计划时,每一次执行这个task的计划执行时间在最初就被定下来了,也就是scheduledExecutionTime(第n次)=firstExecuteTime +n*periodTime;如果第n次执行task时,由于某种原因这次执行时间过长,执行完后的systemCurrentTime>= scheduledExecutionTime(第n+1次),则此时不做period间隔等待,立即执行第n+1次task,而接下来的第n+2次的 task的scheduledExecutionTime(第n+2次)依然还是firstExecuteTime+(n+2)*periodTime这在第一次执行task就定下来了。说白了,这个方法更注重保持执行频率的稳定。
 
Timer的实例:

package com.hemes.timer;

import java.util.*;

public class doTask extends TimerTask {
// true时使用后台进程线程。只要剩下的程序记叙运行,后台进程线程就会执行。 
Timer myTimer;

public void start(int delay, int hour) { 
myTimer = new Timer(); 
    myTimer.schedule(this, delay * 1000, hour*1000*60*60); //利用timer.schedule方法

    //public void schedule(TimerTask task,long time,long period) 
    //task被安排在延迟time后执行,执行后将每隔period(毫秒)反复执行。由于规定的时间间隔并不能保证与时钟精准的同不步,所以该方 
} 

public void start(Date time, int hour) {
myTimer = new Timer();
myTimer.schedule(this, time, hour100060*60); //利用timer.schedule方法

    //public void schedule(TimerTask task,Date time,long period) 
    //task被安排在time指定的时间执行,执行后将每隔period(毫秒)反复执行。由于规定的时间间隔并不能保证与时钟精准的同不步,所以该方 
} 

public void run() { 
//执行任务(sql) 
    System.out.println("do Task..."); 
} 

public void end(){ 
    myTimer.cancel(); 
    //终止Timer的功能执行,但不会对正在执行的任务有影响。当执行cancel方法后将不能再用其分配任务。 
} 

}

调用入口:

         doTask myTask1 = new doTask(); 
       
        //Get the Date corresponding to 11:30:00 pm today. 
        Calendar calendar = Calendar.getInstance(); 
        calendar.set(Calendar.HOUR_OF_DAY, 23); 
        calendar.set(Calendar.MINUTE, 30); 
        calendar.set(Calendar.SECOND, 0); 
        Date time = calendar.getTime();
        myTask1.start(time,24); 
        //myTask1.end();//线程结束 
正文完
可以使用微信扫码关注公众号(ID:xzluomor)
post-qrcode
 0
评论(没有评论)

文心AIGC

2023 年 9 月
 123
45678910
11121314151617
18192021222324
252627282930  
文心AIGC
文心AIGC
人工智能ChatGPT,AIGC指利用人工智能技术来生成内容,其中包括文字、语音、代码、图像、视频、机器人动作等等。被认为是继PGC、UGC之后的新型内容创作方式。AIGC作为元宇宙的新方向,近几年迭代速度呈现指数级爆发,谷歌、Meta、百度等平台型巨头持续布局
文章搜索
热门文章
潞晨尤洋:日常办公没必要上私有模型,这三类企业才需要 | MEET2026

潞晨尤洋:日常办公没必要上私有模型,这三类企业才需要 | MEET2026

潞晨尤洋:日常办公没必要上私有模型,这三类企业才需要 | MEET2026 Jay 2025-12-22 09...
面向「空天具身智能」,北航团队提出星座规划新基准丨NeurIPS’25

面向「空天具身智能」,北航团队提出星座规划新基准丨NeurIPS’25

面向「空天具身智能」,北航团队提出星座规划新基准丨NeurIPS’25 鹭羽 2025-12-13 22:37...
5天连更5次,可灵AI年末“狂飙式”升级

5天连更5次,可灵AI年末“狂飙式”升级

5天连更5次,可灵AI年末“狂飙式”升级 思邈 2025-12-10 14:28:37 来源:量子位 让更大规...
钉钉又发新版本!把 AI 搬进每一次对话和会议

钉钉又发新版本!把 AI 搬进每一次对话和会议

钉钉又发新版本!把 AI 搬进每一次对话和会议 梦晨 2025-12-11 15:33:51 来源:量子位 A...
商汤Seko2.0重磅发布,合作短剧登顶抖音AI短剧榜No.1

商汤Seko2.0重磅发布,合作短剧登顶抖音AI短剧榜No.1

商汤Seko2.0重磅发布,合作短剧登顶抖音AI短剧榜No.1 十三 2025-12-15 14:13:14 ...
最新评论
ufabet ufabet มีเกมให้เลือกเล่นมากมาย: เกมเดิมพันหลากหลาย ครบทุกค่ายดัง
tornado crypto mixer tornado crypto mixer Discover the power of privacy with TornadoCash! Learn how this decentralized mixer ensures your transactions remain confidential.
ดูบอลสด ดูบอลสด Very well presented. Every quote was awesome and thanks for sharing the content. Keep sharing and keep motivating others.
ดูบอลสด ดูบอลสด Pretty! This has been a really wonderful post. Many thanks for providing these details.
ดูบอลสด ดูบอลสด Pretty! This has been a really wonderful post. Many thanks for providing these details.
ดูบอลสด ดูบอลสด Hi there to all, for the reason that I am genuinely keen of reading this website’s post to be updated on a regular basis. It carries pleasant stuff.
Obrazy Sztuka Nowoczesna Obrazy Sztuka Nowoczesna Thank you for this wonderful contribution to the topic. Your ability to explain complex ideas simply is admirable.
ufabet ufabet Hi there to all, for the reason that I am genuinely keen of reading this website’s post to be updated on a regular basis. It carries pleasant stuff.
ufabet ufabet You’re so awesome! I don’t believe I have read a single thing like that before. So great to find someone with some original thoughts on this topic. Really.. thank you for starting this up. This website is something that is needed on the internet, someone with a little originality!
ufabet ufabet Very well presented. Every quote was awesome and thanks for sharing the content. Keep sharing and keep motivating others.
热评文章
读懂2025中国AI走向!公司×产品×人物×方案,最值得关注的都在这里了

读懂2025中国AI走向!公司×产品×人物×方案,最值得关注的都在这里了

读懂2025中国AI走向!公司×产品×人物×方案,最值得关注的都在这里了 衡宇 2025-12-10 12:3...
5天连更5次,可灵AI年末“狂飙式”升级

5天连更5次,可灵AI年末“狂飙式”升级

5天连更5次,可灵AI年末“狂飙式”升级 思邈 2025-12-10 14:28:37 来源:量子位 让更大规...
戴尔 x OpenCSG,推出⾯向智能初创企业的⼀体化 IT 基础架构解决方案

戴尔 x OpenCSG,推出⾯向智能初创企业的⼀体化 IT 基础架构解决方案

戴尔 x OpenCSG,推出⾯向智能初创企业的⼀体化 IT 基础架构解决方案 十三 2025-12-10 1...
九章云极独揽量子位三项大奖:以“一度算力”重构AI基础设施云格局

九章云极独揽量子位三项大奖:以“一度算力”重构AI基础设施云格局

九章云极独揽量子位三项大奖:以“一度算力”重构AI基础设施云格局 量子位的朋友们 2025-12-10 18:...
乐奇Rokid这一年,一路狂飙不回头

乐奇Rokid这一年,一路狂飙不回头

乐奇Rokid这一年,一路狂飙不回头 梦瑶 2025-12-10 20:41:15 来源:量子位 梦瑶 发自 ...