开发中经常遇到用计时器的时候,例如:每秒输出一次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时执行定时任务。
- 创建方式
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); // ALARM_SERVIC是context的一个常量
- 闹钟类型
- RTC_WAKEUP——状态值为0,表示闹钟在睡眠状态下唤醒系统并执行提示功能,绝对时间。
- RTC—— 状态值为1,睡眠状态下不可用,绝对时间。
- ELAPSED_REALTIME——状态值为2,睡眠状态下不可用,相对时间。
- ELAPSED_REALTIME_WAKEUP——状态值为3,睡眠状态下可用,相对时间。
以上绝对时间就是手机的时间,相对时间是相对于当前开机时间来说。
- 常用方法
(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);
该方法也用于设置重复闹钟,与第二个方法相似,区别在于其两次闹钟执行的间隔时间不是固定的。
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)
方法。如果这三种方法错用了的话,虽然不会报错,但是看不到闹钟提示效果。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的三篇文章。