1. 程式人生 > >android 定時任務 Alarm機制

android 定時任務 Alarm機制

Android中定時任務一般有兩種實現方法,一種是使用java API中裡提供的Timer類,一種是使用Android的Alarm機制,這兩種方式都能實現類似的效果,但Timer有一個明顯的短板,它不適合那些需要長期在後代執行的定時任務。我們知道為了讓電池更加耐用,手機都會有自己的休眠策略,Android手機就會在長時間不操作的情況下自動讓CPU進入休眠狀態,就會導致Timer中的定時任務無法正常執行。Alarm機制就不存在這種情況,它具有喚醒CPU的功能,可以保證每次執行定時任務時CPU能正常工作。
1,Alarm機制的用法,它主要就是使用AlaerManager類來實現的,我們通過Context的getService()方法來獲取例項,只是這裡需要傳入的引數Context.ALARM_SERVICE.就可以獲得一個AlarmManage的例項。

        AlarmManager systemService = (AlarmManager)getSystemService(ALARM_SERVICE);

2,AlarmManager常用的有三個方法:

//第一個引數是型別,第二個是執行的時間,第三個是執行的動作
systemService .set(int type,long startTime,PendingIntent pi);
//第一個引數是型別,第二個是首次執行時間,第三個是時間間隔,第三個是執行的動作
systemService .setRepeating(int type,long startTime,long intervalTime,PendingIntent pi);
//與第二個方法相似,不過其兩個執行的間隔時間不是固定的而已。
systemService .setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi);

3,AlarmManager的型別一般有四種:

  • AlarmManager.ELAPSED_REALTIME 表示手機睡眠狀態下不可用,該狀態下鬧鐘使用相對時間(相對於系統啟動開始);
  • armManager.ELAPSED_REALTIME_WAKEUP 表示睡眠狀態下會喚醒系統CPU並執行,該狀態下也使用相對時間);
  • AlarmManager.RTC 表示在睡眠狀態下不可用,該狀態下使用絕對時間,即當前系統時間;
  • AlarmManager.RTC_WAKEUP表示在睡眠狀態下會喚醒系統CPU並執行,該狀態下使用絕對時間;

4,開啟一個服務

Intent intent3 = new Intent(this, LongRunningService.class);
startService(intent3);

5.在Service的OnStartCommand()方法裡寫入

 public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread(new Runnable() {
            @Override
            public void run() {

            }
        }).start();
           AlarmManager systemService = (AlarmManager) getSystemService(ALARM_SERVICE);
            long anHour = 60 * 60 * 1000;//這是一個小數的毫秒數
            long l = SystemClock.elapsedRealtime() + anHour;
             Intent intent9 = new Intent(this, AlarmReceiver.class);
            PendingIntent broadcast = PendingIntent.getBroadcast(this, 0, intent9, 0);
            systemService.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,l,broadcast);
           return super.onStartCommand(intent, flags, startId);
    }

6.在Thread執行緒裡就可以寫入具體的操作,這裡我們用到了一個AlarmReceiver廣播,在廣播裡寫入:

public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent intent1 = new Intent(context, LongRunningService.class);
        context.startService(intent1);
    }
}

7.就這樣服務就會一個每個一個小時就會執行一次,一個在長期在後臺定時執行的服務就完成了。另外Android4.4開始,Alarm任務的觸發時間將會變的不那嗎準,這是因為系統在耗電方面進行了優化,系統會檢測到目前有多少個Alarm任務存在,然後將觸發的時間相近的幾個任務放在一起執行,就可以減少CPU的喚醒次數,從而延長電池壽命.

8.如果想做定時鬧鐘可以用到下面那兩個方法,他是可以保證準確無誤的執行。

   Intent intent = new Intent("com");
        intent.putExtra("com","該吃藥了");
        PendingIntent pi = PendingIntent.getBroadcast(this,0,intent,0);
        AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
        am.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),10*1000,pi);
       String string = intent.getStringExtra("com");  
        Toast.makeText(context,string ,Toast.LENGTH_SHORT).show();  

記得在廣播註冊一下:

        <receiver android:name=".AlarmReceiver">
            <intent-filter>
                <action android:name="com"></action>
            </intent-filter>
        </receiver>