Android开发——定时器处理

  开发中经常遇到用计时器的时候,例如:每秒输出一次log,这时候就要用到延时操作,这里总结了几种常用的方法。

方法一:使用Handler自带的postDelayed(Runnable r, long delayMillis)去完成定时任务
// 定义一个Handler类
private Handler mHandler = new Handler();
// 
private Runnable mRunnable = new Runnable() {
    @Override
    public void run() {
        // 要做的事情
        Log.d("方法一", "1-------1");
        mHandler.postDelayed(this, 1000);
    }
};
// 启动计时器
mHandler.postDelayed(mRunnable, 1000);
// 停止计时器
mHandler.removeCallbacks(mRunnable);
方法二:使用Timer和TimerTask结合
// 定时器
private Timer mTimer = new Timer();
// 定时任务
private TimerTask mTask = new TimerTask() {
    @Override
    public void run() {
       // 要做的事情
        Log.d("方法二", "2-------2");
    }
};

// 启动定时器
mTimer.schedule(mTask, 1000); // 延迟1000毫秒后执行定时任务
mTimer.schedule(mTask, 1000, 1000);// 延迟1000毫秒后执行定时任务,并且每隔1000毫秒执行一次定时任务
// 取消定时器
mTimer.cancel();
方法三:利用Handle子线程处理定时任务
// 
private Handler mMessageHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what){
            case 0:
                // 移除所有的msg.what为0等消息,保证只有一个循环消息队列再跑
                this.removeMessages(0);
                // 要做的事情
               Log.d("方法三", "3-------3");
               this.sendEmptyMessageDelayed(0, 1000);
                break;
            case 1:
                this.removeMessages(0);
                break;
            default:
                break;
        }
    }
};

// 启动方法
mMessageHandler.sendEmptyMessage(0);
// 停止方法
mMessageHandler.sendEmptyMessage(1);
方法四:利用Thread子线程休眠和Handle刷新UI实现定时
// 子线程类
private class TimerThread extends Thread{
    boolean isRunning = false;
    @Override
    public void run() {
        super.run();
        if(isRunning){
            try {
                Thread.sleep(1000);
                Message msg = new Message();
                msg.what = 0;
                mMsgHandler.sendMessage(msg);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
// Handler接收消息执行定时任务
private Handler mMsgHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 0:
                  // 要做的事情
                   Log.d("方法四", "4-------4");
                    break;
                default:
                    break;
            }
        }
    };
  // 定义一个新线程  
  private TimerThread mThread;
  // 开启定时线程
  private void start(){
        if(mThread == null){
            mThread = new TimerThread();
            mThread.isRunning = true;
            mThread.start();
        }
    }
  // 停止定时线程
  private void stop(){
        if(mThread != null){
            mThread.isRunning = false;
            mThread.stop();
            mThread = null;
        }
方法五:利用Android倒计时类CountDownTimer来实现计时
// 自定义一个倒计时类
protected class MyCountdownTimer extends CountDownTimer {

        public MyCountdownTimer(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
        }

        @Override
        public void onTick(long millisUntilFinished) {
            // 计时过程显示
            Log.d("方法五", "5-------5");
        }

        @Override
        public void onFinish() {
            // 计时结束时触发,在这里处理计时结束后要执行的任务
            
        }
    }
    // 倒计时对象
    private MyCountdownTimer mDownTimer = new MyCountdownTimer(3000, 1000);
    // 开启倒计时
    mDownTimer.start();
    // 取消倒计时
    mDownTimer.cancel();
方法六:AlarmManager实现定时功能

   AlarmManager 是Android的全局定时器,可以在指定时间执行定时任务。定时任务通过PendingIntent 的 getActivity()、getService()或 getBroadcast() 来执行。简单的说就是我们设定一个时间,然后在该时间到来时,AlarmManager为我们广播一个我们设定的Intent出来,在接收到设定的Intent时执行定时任务。

  1. 创建方式
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);  // ALARM_SERVIC是context的一个常量
  1. 闹钟类型
  • RTC_WAKEUP——状态值为0,表示闹钟在睡眠状态下唤醒系统并执行提示功能,绝对时间。
  • RTC—— 状态值为1,睡眠状态下不可用,绝对时间。
  • ELAPSED_REALTIME——状态值为2,睡眠状态下不可用,相对时间。
  • ELAPSED_REALTIME_WAKEUP——状态值为3,睡眠状态下可用,相对时间。
    以上绝对时间就是手机的时间,相对时间是相对于当前开机时间来说。
  1. 常用方法
    (1)set(int type,long startTime,PendingIntent pi);
    该方法用于设置一次性闹钟,其中参数说明如下:
    type:闹钟类型
    startTime:首次执行闹钟的时间
    pi:闹钟响应动作

(2)setRepeating(int type,long startTime,long intervalTime,PendingIntent pi);
该方法用于设置重复闹钟,其中参数说明如下:
type:闹钟类型
startTime:首次执行闹钟的时间
intervalTime:两次执行闹钟的时间间隔
pi:闹钟响应动作

(3)setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi);
该方法也用于设置重复闹钟,与第二个方法相似,区别在于其两次闹钟执行的间隔时间不是固定的。

  1. PendingIntent 介绍
      PendingIntent是Intent的封装类,我们通过PendingIntent添加指定的Intent设定,便于接收指定的广播时执行定时任务。PendingIntent对象的获取途径有三种,如果是通过启动服务来实现闹钟提示的话,PendingIntent对象的获取就应该采用Pending.getService(Context c,int i,Intent intent,int j)方法;如果是通过广播来实现闹钟提示的话,PendingIntent对象的获取就应该采用PendingIntent.getBroadcast(Context c,int i,Intent intent,int j)方法;如果是采用Activity的方式来实现闹钟提示的话,PendingIntent对象的获取就应该采用PendingIntent.getActivity(Context c,int i,Intent intent,int j)方法。如果这三种方法错用了的话,虽然不会报错,但是看不到闹钟提示效果。

  2. AlarmManager的使用方式

//获取AlarmManager实例
AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
int anHour =  6 * 1000 ;  // 6秒
long triggerAtTime = SystemClock.elapsedRealtime() + anHour;
Intent intent = new Intent(this, AlarmReceiver.class);
intent.setAction("alarm_intent_action");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, 0);
//开启提醒
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);

// 定义广播接收器:
public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // 这里收到定时广播,处理定时任务
        Log.d("方法六", "6-------6");
    }
}

// 在配置文件中注册广播接收器
<receiver 
    android:name=".AlarmReceiver" 
    android:process=":remote">
</receiver>

// 取消闹钟
AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
intent.setAction("alarm_intent_action");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, 0);
manager.cancel(pi);
// 取消闹钟时,一定要再重新创建所有的对象包括:Intent,PendingIntent,AlarmManager对象

   AlarmManager实现定时的方法,我还没有用到过,以上内容是在网上查找资料后自己在一个小demo中小小试验了的,有错误或描述不清的地方请见谅。下面是我参考的介绍AlarmManager的三篇文章。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容