首页 > 系统 > Android > 正文

android倒计时

2019-11-06 09:51:17
字体:
来源:转载
供稿:网友

Handler

通过调用Thread类的 start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,但此时并没有运行,它需要CPU时间片。一旦得到CPU时间片,就会执行run()方法。run()的方法体称为线程体,它包含了要执行的这个线程的内容,run()方法运行结束,此线程也随即终止。经过测试,这种倒计时方式锁屏之后20s左右就会失效(timer不会失效)
mHandler.postDelayed(new Runnable() {    @Override    public void run() {        mHandler.postDelayed(this, 1000);    }}, 1000);

Timer

    一个Timer内部封装装了“一个Thread”和“一个TimerTask队列”,这个队列按照一定的方式将任务排队处理。封装的Thread在Timer的构造方法调用时被启动,这个Thread的run方法按照条件去循环这个TimerTask队列,然后调用TimerTask的run方法。 但是,如果CPU进入了休眠状态,那么这个thread将会因为失去CPU时间片而阻塞,从而造成我们需要的定时任务失效。

样例:自定义一个button,点击之后开启倒计时,并在button上显示剩余时间,同时要确保锁屏之后继续正常倒计时(handler锁屏会失效)。

创建一个TimeButton集成Button

public class TimeButton extends Button{

初始化定时器

PRivate void initTimer(){        timer = new Timer();        task = new TimerTask() {            @Override            public void run() {                mHandler.sendEmptyMessage(777);            }        };    }

启动定时器

public void start(){    initTimer();    timer.schedule(task , 0 , 1000);//延迟0s,每隔1s执行一次run方法
    this.setText(cycle + "");}定期刷新Button的text

Handler mHandler = new Handler(){    @Override    public void handleMessage(Message msg) {        super.handleMessage(msg);        switch (msg.what){            case 777:                cycle -= space;                if(cycle > 0 ){                    TimeButton.this.setText((cycle/1000) + "s");                }else {                    TimeButton.this.setText("重新获取");                    onDestory();                }                break;        }    }};

CountDownTimer

这是Android自己封装的计时器,使用起来非常简单。但是经过测试,发现这种方式如果间隔设定为1s,每隔10s这个onTick()方法会少执行一次,及只执行了9次。

CountDownTimer timer = new CountDownTimer(20000 , 1000) {//参数(周期,间隔)    //每隔时间间隔执行一次    @Override    public void onTick(long millisUntilFinished) {        tv_number.setText(millisUntilFinished/1000 + "s");    }    //循环结束执行    @Override    public void onFinish() {        tv_number.setText("倒计时完了");    }};

它的底层实现源码

public CountDownTimer(long millisInFuture, long countDownInterval) {    mMillisInFuture = millisInFuture;    mCountdownInterval = countDownInterval;}
public synchronized final CountDownTimer start() {    mCancelled = false;    if (mMillisInFuture <= 0) {        onFinish();        return this;    }    mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;    mHandler.sendMessage(mHandler.obtainMessage(MSG));    return this;}
private Handler mHandler = new Handler() {    @Override    public void handleMessage(Message msg) {        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);            }        }    }};

AlarmManager

        AlarmManager将应用与服务分割开来后,使得应用程序开发者不用 关心具体的服务,而是直接通过AlarmManager来使用这种服务。这也许就是客户/服务模式的好处吧。    当我们在开发android程序时,有些用户会使用service来管理一些后台的任务,如网络操作,或者间断处理数据等,这些用户需要在用户关闭程序,或者关闭屏幕后也能处理后台任务,可android手机为了节省电池使用,当用户关闭屏幕后,会将cpu置于休眠状态,当休眠状态启动,我们的服务就处于暂停状态了.为了斛决这个问题,android库里就提供了一个AlarmManager的库,AlarmManager是客户/服务模式的模式,也就是说AlarmManager是由系统来管理,而不是我们应用程序的一部分,也就是说AlarmManager是全局的,当我们的程序启用AlarmManager后,就给系统注册了一个服务,该服务会根据你设置的参数定时的向你的应用程序发送消息(注意,此消息以广播方式发送).
am = (AlarmManager)getSystemService(ALARM_SERVICE);int hour = 28 * 60 * 1000;long targetTime = System.currentTimeMillis() + hour; //其中SystemClock.elapsedRealtime()表示开机到现在的时间Intent intent1 = new Intent(this , GetTokenCastReciver.class);pi = PendingIntent.getBroadcast(this, 0, intent1, 0);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {    am.setExact(AlarmManager.RTC_WAKEUP, targetTime, pi);}else {    am.set(AlarmManager.RTC_WAKEUP, targetTime, pi);}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表