AlarmManager api詳解

轉載地址:http://blog.csdn.net/aa20616012/article/details/50497536 

http://www.tuicool.com/articles/EFNfYvI
http://blog.csdn.net/mafei852213034/article/details/50858997
http://blog.csdn.net/BingShuShu/article/details/50433643

http://blog.csdn.net/mr_liabill/article/details/49451509
https://github.com/kesenhoo/android-training-course-in-chinese/blob/master/background-jobs/scheduling/alarms.md

AlarmManager使用

AlarmManager簡介 

AlarmManager接口 
常用接口 
Alarm問題分析 
Batch隊列裏面的一個Batch 
非喚醒alarm延時統計 
Top Alarm 
Alarm統計 
反饋與建議

AlarmManager簡介

AlarmManager這個類提供對系統鬧鐘服務的訪問接口。你可以爲你的應用設定一個在未來某個時間喚醒的功能。當鬧鐘響起,實際上是系統發出了爲這個鬧鐘註冊的廣播,會自動開啓目標應用。註冊的鬧鐘在設備睡眠的時候仍然會保留,可以選擇性地設置是否喚醒設備,但是當設備關機和重啓後,鬧鐘將會被清除。

在alarm的receiver的onReceive()方法被執行的時候,AlarmManager持有一個CPU喚醒鎖,這樣就保證了設備在處理完廣播之前不會sleep。一旦onReceive()方法返回,AlarmManager就會釋放這個鎖,表明一些情況下可能onReceive()方法一執行完設備就會sleep。如果你的alarmreceiver中調用了Context.startService(),那麼很可能service還沒起來設備就sleep了。爲了阻止這種情況,你的BroadcastReceiver和Service需要實現不同的喚醒鎖機制,來確保設備持續運行到service可用爲止。

注意:Alarm Manager主要是用來在特定時刻運行你的代碼,即便是你的應用在那個特定時刻沒有跑的情況。對於常規的計時操作(ticks, timeouts, etc),使用Handler處理更加方便和有效率。另:從API 19開始,alarm的機制都是非準確傳遞,操作系統將會轉換鬧鐘,來最小化喚醒和電池使用。有一些新的API會支持嚴格準確的傳遞,見 setWindow(int, long, long, PendingIntent)和setExact(int, long, PendingIntent)。targetSdkVersion在API19之前應用仍將繼續使用以前的行爲,所有的鬧鐘在要求準確傳遞的情況下都會準確傳遞。

AlarmManager接口


1、 cancel(PendingIntent operation) Remove any alarms with a matching Intent.

2、 changeAlarmType(String pkgName, boolean wakeup)

3、 getNextAlarmClock()

Gets information about the next alarm clock currently scheduled.

4、 set(int type, long triggerAtMillis, PendingIntent operation)

Schedule an alarm.

5、 setAlarmClock(AlarmManager.AlarmClockInfo info, PendingIntent operation)

Schedule an alarm that represents an alarm clock.

6、 setExact(int type, long triggerAtMillis, PendingIntent operation)

Schedule an alarm to be delivered precisely at the stated time.

7、 setInexactRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)

Schedule a repeating alarm that has inexact trigger time requirements; for example, an alarm that repeats every hour, but not necessarily at the top of every hour.

8、 setRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)

Schedule a repeating alarm.

9、 setTime(long millis)

Set the system wall clock time.

10、 setTimeZone(String timeZone)

Set the system default time zone.

11、 setWindow(int type, long windowStartMillis, long windowLengthMillis, PendingIntent operation)

Schedule an alarm to be delivered within a given window of time. 

常用接口

public void cancel (PendingIntent operation)

 移除intent相匹配的alarm(只要action,data, type,class,categories相等,就會被取消)
Remove any alarms with a matching Intent. Any alarm, of any type, whose Intent matches this one (as defined by filterEquals(Intent)), will be canceled.

public void set(int type, long triggerAtMillis, PendingIntent operation)

 該方法用於設置一次性鬧鐘
第一個參數int type 指定定時服務的類型,該參數接受如下值:
ELAPSED_REALTIME: 在指定的延時過後,發送廣播,但不喚醒設備(鬧鐘在睡眠狀態下不可用)。如果在系統休眠時鬧鐘觸發,它將不會被傳遞,直到下一次設備喚醒。
ELAPSED_REALTIME_WAKEUP 在指定的延時過後,發送廣播,並喚醒設備(即使關機也會執行operation所對應的組件)。延時是要把系統啓動的時間SystemClock.elapsedRealtime()算進去的,具體用法看代碼。
RTC: 指定當系統調用System.currentTimeMillis()方法返回的值與triggerAtTime相等時啓動operation所對應的設備(在指定的時刻,發送廣播,但不喚醒設備)。如果在系統休眠時鬧鐘觸發,它將不會被傳遞,直到下一次設備喚醒(鬧鐘在睡眠狀態下不可用)。
RTC_WAKEUP: 指定當系統調用System.currentTimeMillis()方法返回的值與triggerAtTime相等時啓動operation所對應的設備(在指定的時刻,發送廣播,並喚醒設備)。即使系統關機也會執行 operation所對應的組件。
第二個參數triggerAtMillis表示觸發鬧鐘的時間。
第三個參數PendingIntent operation表示鬧鐘響應動作:
PendingIntent operation:是鬧鐘的執行動作,比如發送一個廣播、給出提示等等。PendingIntent是Intent的封裝類。需要注意的是:
啓動服務:如果是通過啓動服務來實現鬧鐘提示的話,PendingIntent對象的獲取就應該採用Pending.getService(Context c,int i,Intent intent,int j)方法;
啓動廣播:如果是通過廣播來實現鬧鐘提示的話,PendingIntent對象的獲取就應該採用PendingIntent.getBroadcast(Context c,inti,Intent intent,int j)方法;
啓動activity:如果是採用Activity的方式來實現鬧鐘提示的話,PendingIntent對象的獲取就應該採用PendingIntent.getActivity(Context c,inti,Intent intent,int j)方法。
如果這三種方法錯用了的話,雖然不會報錯,但是看不到鬧鐘提示效果。
 注意:AndroidL開始,設置的alarm的觸發時間必須大於當前時間 5秒 
AlarmManagerService中是通過PendingItent來標示一個Alarm的
AndroidL開始系統有了非喚醒Alarm在黑屏狀況下會推遲觸發,推遲的時間通過當前黑屏時間計算出來,但一但有喚醒Alarm,則隨着觸發
MTK平臺關閉了該功能,三星平臺依然保留該功能

public void setRepeating(int type,long startTime,long intervalTime,PendingIntent pi)

設置一個週期性執行的定時服務。第一個參數表示鬧鐘類型,第二個參數表示鬧鐘首次執行時間,第三個參數表示鬧鐘兩次執行的間隔時間,第三個參數表示鬧鐘響應動作。

注意:改方法提供了設置週期鬧鐘的入口,鬧鐘執行時間嚴格按照startTime來處理,使用該方法需要的資源更多,不建議使用。

public void setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi)

 該方法也用於設置重複鬧鐘,與第二個方法相似,不過其兩個鬧鐘執行的間隔時間不是固定的而已。它相對而言更省電(power-efficient)一些,因爲系統可能會將幾個差不多的鬧鐘合併爲一個來執行,減少設備的喚醒次數。第三個參數intervalTime爲鬧鐘間隔,內置的幾個變量如下:
INTERVAL_DAY: 設置鬧鐘,間隔一天
INTERVAL_HALF_DAY: 設置鬧鐘,間隔半天
INTERVAL_FIFTEEN_MINUTES設置鬧鐘,間隔15分鐘
INTERVAL_HALF_HOUR: 設置鬧鐘,間隔半個小時
INTERVAL_HOUR: 設置鬧鐘,間隔一個小時
 AndroidL開始repeat的週期必須大於60秒

Alarm問題分析


1.dumpsys alarm

查看設置的alarm

 Current Alarm Manager state:
nowRTC=1452484905420=2016-01-11 12:01:45 nowELAPSED=+2d19h30m57s573ms
Time since non-interactive: +8m29s723ms 從上一次滅屏開始計算的時間
Max wakeup delay: +15m0s0ms 最大的喚醒延時
Time since last dispatch: +1s746ms 距離上一個觸發alarm的時間
Next non-wakeup delivery time: -21m44s581ms 下一個非喚醒alarm觸發時間
Next non-wakeup alarm: +14s580ms = 2016-01-11 12:02:00 下一個非喚醒alarm觸發時間
Next wakeup: +1h2m30s289ms = 2016-01-11 13:04:15 下一次喚醒時間
Num time change events: 1 時間改變的次數
Pending alarm batches: 21 在隊列中的alarm

Batch隊列裏面的一個Batch

 Batch{18f03fc3 num=3 start=286152153 end=286152153}:
RTC #2: Alarm{258ac040 type 1 when 00:00:00 start 23:59:59 end 00:00:00 com.meizu.flyme.launcher}
tag=*alarm*:notify.launcher.date.change
type=1 whenElapsed=+8h27m32s45ms when=2016-01-12 00:00:00
start =00:00:00 whenElapsed=00:00:00 end=00:00:00 fixed=true aligned=false window=-1 repeatInterval=0 count=0
operation=PendingIntent{34278b79: PendingIntentRecord{19eb70be com.meizu.flyme.launcher broadcastIntent}}
RTC #1: Alarm{368d151f type 1 when 00:00:00 start 00:00:00 end 00:00:00 com.meizu.flyme.input}
tag=*alarm*:notify.ime.date.change
type=1 whenElapsed=+8h27m32s45ms when=2016-01-12 00:00:00
start =23:59:59 whenElapsed=00:00:00 end=00:00:00 fixed=true aligned=false window=-1 repeatInterval=0 count=0
operation=PendingIntent{2b7ba06c: PendingIntentRecord{2e0c6635 com.meizu.flyme.input broadcastIntent}}
RTC #0: Alarm{3070ddc8 type 1 when 00:00:00 start 00:00:00 end 00:00:00 com.android.calendar}
tag=*alarm*:com.android.calendar.APPWIDGET_SCHEDULED_UPDATE
type=1 whenElapsed=+8h27m32s45ms when=2016-01-12 00:00:00
start =00:00:00 whenElapsed=00:00:00 end=00:00:00 fixed=true aligned=false window=0 repeatInterval=0 count=0
operation=PendingIntent{14518e61: PendingIntentRecord{38b85758 com.android.calendar broadcastIntent}}

非喚醒alarm延時統計

 Past-due non-wakeup alarms: (none)
Number of delayed alarms: 482, total delay time: +1d22h49m26s7ms
Max delay time: +1h29m59s657ms, max non-interactive time: +2d16h18m22s465ms

Top Alarm

 Top Alarms:
+59s476ms running, 0 wakeups, 316 alarms: 1000:android
*alarm*:android.intent.action.TIME_TICK
+42s217ms running, 0 wakeups, 143 alarms: 1000:android
*alarm*:com.android.server.action.NETWORK_STATS_POLL
+25s765ms running, 0 wakeups, 48 alarms: 1000:com.meizu.safe
*alarm*:pm.nonwakeup.powergauge.stats
+20s491ms running, 0 wakeups, 23 alarms: 1000:android
*alarm*:android.appwidget.action.APPWIDGET_UPDATE
+17s353ms running, 0 wakeups, 11 alarms: 1000:android
*alarm*:android.content.jobscheduler.JOB_DELAY_EXPIRED
+16s417ms running, 5 wakeups, 5 alarms: u0a3:com.android.providers.calendar
*walarm*:com.android.providers.calendar.intent.CalendarProvider2
+10s623ms running, 15 wakeups, 15 alarms: u0a29:com.android.systemui
*walarm*:com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD
+6s406ms running, 0 wakeups, 3 alarms: 1000:android
*alarm*:android.intent.action.DATE_CHANGED
+5s186ms running, 0 wakeups, 8 alarms: 1000:com.meizu.experiencedatasync
*alarm*:com.meizu.usagestats.check_upload
+3s695ms running, 0 wakeups, 7 alarms: 1000:android
*alarm*:android.content.jobscheduler.JOB_DEADLINE_EXPIRED

Alarm統計


 

Alarm Stats:
1000:android +1m53s845ms running, 14 wakeups:
+59s476ms 0 wakes 316 alarms: alarm:android.intent.action.TIME_TICK
+42s217ms 0 wakes 143 alarms: alarm:com.android.server.action.NETWORK_STATS_POLL
+20s491ms 0 wakes 23 alarms: alarm:android.appwidget.action.APPWIDGET_UPDATE
………………………. 
alarm:com.android.server.action.UPDATE_APPROXIMATELY_TWILIGHT_STATE
+132ms 8 wakes 8 alarms: 
walarm:com.android.server.task.controllers.BatteryController.ACTION_CHARGING_STABLE
+130ms 3 wakes 3 alarms: 
1000:com.meizu.safe +26s53ms running, 6 wakeups:
+25s765ms 0 wakes 48 alarms: alarm:pm.nonwakeup.powergauge.stats
+131ms 3 wakes 3 alarms: walarm:tmsdk.common.actionreport
………………………… 
1000:com.meizu.experiencedatasync +7s448ms running, 0 wakeups:
+5s186ms 0 wakes 8 alarms: alarm:com.meizu.usagestats.check_upload
+2s262ms 0 wakes 2 alarms: alarm:com.meizu.experiencedatasync.check_upload
u0a3:com.android.providers.calendar +18s156ms running, 8 wakeups:
+16s417ms 5 wakes 5 alarms: 
walarm:com.android.providers.calendar.intent.CalendarProvider2
+1s739ms 3 wakes 3 alarms: 
walarm:com.android.providers.calendar.SCHEDULE_ALARM
u0a5:com.meizu.customizecenter +1s282ms running, 0 wakeups:
+1s282ms 0 wakes 5 alarms: 
alarm:com.meizu.customizecenterservice.download.CHECK_UPDATE
u0a13:com.meizu.flyme.launcher +1s522ms running, 0 wakeups:
+1s522ms 0 wakes 3 alarms: 
alarm:notify.launcher.date.change
u0a22:com.meizu.flyme.input +1s599ms running, 0 wakeups:
+1s599ms 0 wakes 3 alarms: 
alarm:notify.ime.date.change
u0a29:com.android.systemui +10s623ms running, 15 wakeups:
+10s623ms 15 wakes 15 alarms: 
walarm:com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD 

反饋與建議

如以上描述有問題的地方或者有其他建議,請發郵件給我,如果大家有更多的經驗總結,還請不吝賜教,我將持續完善此文檔,謝謝!。

發佈了183 篇原創文章 · 獲贊 32 · 訪問量 42萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章