定时任务之Alarm

2019-03-13  本文已影响0人  俗人浮生

之前我们已经简单说了定时任务的几种方式,详见:定时任务
今天我们来看看如何用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。

上一篇下一篇

猜你喜欢

热点阅读