android 计数器---定时执行任务

定时执行任务,大家都会想到timer或者thread,确实,这两者都能达到。
好吧,还是先说需求
自动每隔10秒执行一次任务,如果点击了某个按钮,则立即执行任务,并重新计时,也就是说从点击按钮开始再隔10秒才会执行任务。

用timer怎么实现?

我做不到,我不知道怎么修改timer的计时器

用thread怎么实现?

开一个线程,用一个变量记录这一次执行任务的时间(按按钮或者自动执行),一个while循环不断获取当前时间,如果满足10秒,执行,并修改执行任务的时间为当前时间;点击按钮,执行任务,并修改执行任务的时间为当前时间。

android中怎么做?

用android.os.CountDownTimer
CountDownTimer是在handler中进行逻辑处理的,主要是靠发送延迟消息来计时
CountDownTimer,会先判断距离剩余时间是否小于0,如果小于0,调用onfinish,如果在0~timeInterval之间,也会sendmessageDelay,也就是说,最后还会执行一次,
如果大于timeInterval,则逻辑处理,触发任务,sendmessageDelay.
里面有一点很有意思的代码 handler中的

synchronized (CountDownTimer.this) {
                if (mCancelled) {
                    return;
                }

                final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();

                if (millisLeft <= 0) {
                    onFinish();
                } else if (millisLeft < mCountdownInterval) {
                    // no tick, just delay until done
                    sendMessageDelayed(obtainMessage(MSG), millisLeft);
                } else {
                    long lastTickStart = SystemClock.elapsedRealtime();
                    onTick(millisLeft);

                    // take into account user's onTick taking time to execute
                    long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();

                    // special case: user's onTick took more than interval to
                    // complete, skip to next interval
                    while (delay < 0) delay += mCountdownInterval;

                    sendMessageDelayed(obtainMessage(MSG), delay);
                }
            }

注意那个while循环 22 行,我第一眼还以为是这里为了延时的处理,后来一想,不对,handler是在主线程中的,主线程怎么能延时呢?
其实注释已经很清楚了,就是保证delay大于0。
可以说是一开始执行就计时,
执行前的时间 + 时间间隔 - 现在的时间 = 需要延时的时间
如果执行了很长时间,大于了间隔时间,那么得到的延时时间就是负数,这是不行的。

但是,用在需求上,这就不好做了,如果我们在timer结束的时候调用cancle再start,假设是参数是5000,3000,也就是说,会在3秒之后的2秒后cancle,再start,start会sendmessage,然后handler中进行任务触发,并sendmessageDelay,也就是说是隔了2秒就执行了
这不符合我们的需求,那么改一改源码

        // 只要小于间隔时间,就不再执行任务
                if (millisLeft < mCountdownInterval){
                   onFinish();
                }  else {
                ......

小于间隔,我们就onfinish,在onfinish中cancle,然后start


        long time = System.currentTimeMillis();
        Log.e("tag","time " + time);

//        countDownTimer = new CountDownTimer(3000, 3000) {
        countDownTimer = new CountTimer(3000, 3000) {
            @Override
            public void onTick(long millisUntilFinished) {
                handler.sendEmptyMessage(1);
                long time = System.currentTimeMillis();
                Log.e("tag","time " + time);
            }

            @Override
            public void onFinish() {
                cancel();
                start();
            }
        }.start();

建议 arg1 < arg0 < 2 * arg1

代码已上传
如果发现bug,或需要优化的地方,请及时告知


最后欢迎关注我的微信公众号:云端看大地
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值