定時任務之Alarm

之前我們已經簡單說了定時任務的幾種方式,詳見:定時任務
今天我們來看看如何用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。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 有時候,閑不住是一種好習慣。 我這人有個臭毛病,就是不愛閑著。閑的沒事就愛瞎看瞎溜達,比如把自己的手機相冊挨個翻一...
    葉子綠漫天閱讀 543評論 5 3
  • 素來就不喜歡下雨,尤其是春雨。 春雨總是纏纏綿綿拖拖拉拉,像一位癡情的女子,明明感情已經結束,卻仍舊站在小巷的盡頭...
    初凈閱讀 349評論 0 0