AlarmManager理解
来源:互联网 发布:剑网三苍爹捏脸数据 编辑:程序博客网 时间:2024/05/16 09:11
哎,最近刚刚开始做framework开发。主要做些BUG修改之类的。刚进公司。进项目组,由于之前不是做framework开发,所以很生疏。我接到的第一个任务就是移植工厂测试工具MMI.
好不容易移植到系统中去了以后呢。在各个测试项复查的过程中发现有几个case测试通不过。AlarmManager.setRepeating就是让我很头疼。我是想在一秒钟重复一次。但是始终不行,所以分析了一些源码,记录一下,以后好复习。
AlarmManager.setRepeating(int type, long triggerAtMillis, long intervalMillis,PendingIntent operation)这几个参数我就不对说了,可以参考http://blog.csdn.net/ricks_wu/article/details/22494015。比较详细。
我们使用的AlarmManager类其实是很简单的一个包装类。他在android.app下。
AlarmManager的成员函数有:
AlarmManager(IAlarmManager service)publicvoid set(int type,long triggerAtTime, PendingIntent operation)publicvoid setRepeating(int type,long triggerAtTime,long interval,PendingIntent operation)publicvoid setInexactRepeating(int type,long triggerAtTime,long interval,PendingIntent operation)publicvoid cancel(PendingIntent operation)publicvoid setTime(long millis)publicvoid setTimeZone(String timeZone)
try { mService.set(type, triggerAtMillis, windowMillis, intervalMillis, operation, workSource, alarmClock); } catch (RemoteException ex) { }
对就是调用的<span style="font-family: consolas, 'Courier New', courier, monospace;">mService,那它是什么呢?</span><pre name="code" class="java">private final IAlarmManager mService;
继续跟踪会发现,它其实就是AlarmManagerService里面的IBind一个对象。熟悉IPC的就不会很生疏了,
class AlarmManagerService extends SystemService{、
<span style="white-space:pre"></span>....
<span style="white-space:pre"></span><pre name="code" class="java"><span style="white-space:pre"></span>private final IBinder mService = new IAlarmManager.Stub() { @Override public void set(int type, long triggerAtTime, long windowLength, long interval, PendingIntent operation, WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock) { if (workSource != null) { getContext().enforceCallingPermission( android.Manifest.permission.UPDATE_DEVICE_STATS, "AlarmManager.set"); } setImpl(type, triggerAtTime, windowLength, interval, operation, windowLength == AlarmManager.WINDOW_EXACT, workSource, alarmClock); } @Override public boolean setTime(long millis) { } @Override public void setTimeZone(String tz) { } @Override public void remove(PendingIntent operation) { } @Override public AlarmManager.AlarmClockInfo getNextAlarmClock(int userId) { } @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { } @Override public void updateBlockedUids(int uid, boolean isBlocked) { } };
<span style="white-space:pre"></span>....
}
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(), 1 * 1000,pendingIntent);就会调用到这里的
AlarmManager:
public void setRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation) { setImpl(type, triggerAtMillis, legacyExactLength(), intervalMillis, operation, null, null); }
注意这里legacyExactLength(); 看看它:
<span style="white-space:pre"></span>AlarmManager(IAlarmManager service, Context ctx) { mService = service; final int sdkVersion = ctx.getApplicationInfo().targetSdkVersion; mAlwaysExact = (sdkVersion < Build.VERSION_CODES.KITKAT);//<span style="font-family: Arial, Helvetica, sans-serif;">Build.VERSION_CODES.KITKAT=19</span> } private long legacyExactLength() { return (mAlwaysExact ? WINDOW_EXACT : WINDOW_HEURISTIC);//<span style="font-family: Arial, Helvetica, sans-serif;">WINDOW_EXACT=0;</span><span style="font-family: Arial, Helvetica, sans-serif;">WINDOW_HEURISTIC = -1;</span> }
mAlwaysExact?是什么? 在AlarmManager 构造函数里面可以看到他。
这里是在比较版本。如果是在19以后则不能精确发生,在19之前可以做到时间精确提醒,说是为了节约使用电量,所以害得我在5.1手机上始终无法得到1秒钟唤醒一次。
接下来去到了
AlarmManagerService的<pre name="code" class="java" style="color: rgb(51, 51, 51); font-size: 13px; line-height: 23px;">IBinder mService了。
setImpl(type, triggerAtTime, windowLength, interval, operation, windowLength == AlarmManager.WINDOW_EXACT, workSource, alarmClock); //<span style="font-family: Arial, Helvetica, sans-serif;">AlarmManager.WINDOW_EXACT =0</span>
注意这里第6个参数
windowLength == AlarmManager.WINDOW_EXACT
windowLength在19以后是-1 在19之前是0.
所以第六个参数是false.调用AlarmManagerService的setImpl方法如下:
void setImpl(int type, long triggerAtTime, long windowLength, long interval, PendingIntent operation, boolean isStandalone, WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock) {<pre name="code" class="java"><span style="white-space:pre"></span>..........// Sanity check the recurrence interval. This will catch people who supply // seconds when the API expects milliseconds. if (interval > 0 && interval < MIN_INTERVAL) {
<span style="white-space:pre"></span>Slog.w(TAG, "Suspiciously short interval " + interval + " millis; expanding to " + (int)(MIN_INTERVAL/1000) + " seconds"); interval = MIN_INTERVAL; }<span style="white-space:pre"></span>.......... }
// Minimum alarm recurrence interval private static final long MIN_INTERVAL = 60 * 1000; // one minute, in millis
哇。就在这里处理了我的时间,如果重复的时间小于1一分钟。则设置为一分钟,难怪我始终1秒钟始终不行啊。。。。晕哦。
哎。搞里半天是这里的问题。如果我就是要在1S后执行呢,放心Google提供了一个新方法:setExact去实现精确的时间提醒。
- AlarmManager理解
- AlarmManager---帮助理解AIDL
- AlarmManager
- AlarmManager
- AlarmManager
- AlarmManager
- AlarmManager
- AlarmManager
- AlarmManager
- AlarmManager
- AlarmManager
- AlarmManager
- AlarmManager
- AlarmManager
- AlarmManager
- AlarmManager
- alarmManager
- AlarmManager
- C. Case of Matryoshkas( Codeforces Round #310 (Div. 2) 模拟)
- Delphi开发学习二:使用ADOQuery控件对SQL数据库表进行操作
- QTableWidget详解(样式、右键菜单、表头塌陷、多选等)
- error while loading shared libraries: libssl.so.6
- HDUOJ_2544(最短路)(dijkstra)
- AlarmManager理解
- 实训仿QQ电话本-知识总结
- IOS 7+ 生成二维码图片
- 黑马程序员——JAVA基础之面向对象(上)
- HDOJ 4460 Friend Chains 图的最长路
- 文件、颜色、字体标准对话框使用
- 如何学习FPGA——转自网络
- oracle学习之第一个存储过程:打印Hello World
- mysql数据库root用户密码忘记进行修改的办法