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的textHandler 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);}
新闻热点
疑难解答