之前我们已经简单说了定时任务的几种方式,详见:定时任务
今天我们来看看如何用Android的Alarm机制来做定时任务的,还是之前的定时任务:从1到10每隔1秒进行数数,废话不多说,直接上代码:
public class MyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService");
}
@Override
public void onCreate() {
super.onCreate();
LogUtil.loge("创建");
}
@Override
public void onDestroy() {
super.onDestroy();
LogUtil.loge("销毁");
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
long count = intent.getLongExtra("count", 0);
if(count<10){
count++;
LogUtil.loge("count: " + count);
AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
long triggerAtTime = SystemClock.elapsedRealtime() + 1000;
intent.putExtra("count",count);
//因使用更换了intent中的count值,这里需要用FLAG_UPDATE_CURRENT这个Flag
PendingIntent pendingIntent=PendingIntent.getService(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
//Android 4.4 版本开始,Alarm 任务的触发时间将会变得不准确,如果对时间要求严格,可用setExact()方法来替代set()
if (Build.VERSION.SDK_INT >=19){
manager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pendingIntent);
} else{
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pendingIntent);
}
}
}
}
}
我们是直接利用IntentService来做具体定时任务的实现,相关注意要点注释已经说明了,然后调用方法也非常简单,如下:
Intent intent=new Intent(context,MyIntentService.class);
startService(intent);
这样确实能够实现定时任务,但后来笔者阅读了相关文档,发现AlarmManager还支持设置周期性定时任务,那么,上面的代码肯定是可以进行优化的,毕竟没必要每次执行完定时任务后,再重新启动一个定时任务,直接用周期性定时任务会更合理些,说改就改,还是直接上代码:
public class MyIntentService2 extends IntentService {
private static long count=0;
public MyIntentService2() {
super("MyIntentService2");
}
@Override
public void onCreate() {
super.onCreate();
LogUtil.loge("创建");
}
@Override
public void onDestroy() {
super.onDestroy();
LogUtil.loge("销毁");
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
if(count<10){
count++;
LogUtil.loge("count: " + count);
}else {
//关闭Alarm
AlarmManager manager = (AlarmManager) Global.getContext().getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(Global.getContext(),MyIntentService2.class);
PendingIntent pendingIntent=PendingIntent.getService(Global.getContext(),0,i,PendingIntent.FLAG_UPDATE_CURRENT);
if(pendingIntent!=null){
manager.cancel(pendingIntent);
}
LogUtil.loge("关闭Alarm");
}
}
}
}
再看看调用的方法,代码如下:
AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
long triggerAtTime = SystemClock.elapsedRealtime();
Intent intent=new Intent(context,MyIntentService2.class);
PendingIntent pendingIntent=PendingIntent.getService(Global.getContext(),0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
manager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime,1000, pendingIntent);
注意到我们用的是setInexactRepeating,据说这个方法优化了很多,最主要的是省电。同时,既然是周期性定时任务,那么,当周期性定时任务完成之后,请注意关闭Alarm。
网友评论