AlarmManager用法的注意事项 |
您所在的位置:网站首页 › 如何调闹钟和定时闹钟的区别 › AlarmManager用法的注意事项 |
1、概述
最近在使用AlarmManager做周期性定时任务时发现在很短的时间内出现了重复的响应。 于是查看了下alarmmanager的说明并记录demo中alarm的表现方式。 2、Alarm Type从android提供的闹钟方法来看,都要指定一个alarmtype。alarmtype是一个枚举常量,有四个取值,分别为 RTC_WAKEUP, RTC, ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME。 这四个类型表明了闹钟的计时方式和响应时是否唤醒cpu。 2.1、RTC_WAKEUP该字段android源码说明如下:
You can’t set the time when the device will go to sleep because the system decides that. It’s actually “display sleep”. Imagine you’re downloading an apk from the Play store. Should the download stop just because you told the device to “sleep” after X seconds? Of course not. 2.3、ELAPSED_REALTIME_WAKEUP
单次的定时操作方法有精准和不精准两种类型,如下: alarmManager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), pendingIntent); alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), pendingIntent);如果要使用精确的闹钟时,则需使用第一个接口。 对于set方法,源码解释如下: Applications whose {@code targetSdkVersion} is before API 19 will continue to get the previous alarm behavior: all of their scheduled alarms will be treated as exact. 也即set方法在api 19以后是不精确的闹钟。这一点需要注意。 4、周期性的定时操作使用周期性的闹钟定时接口如下: alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), intervalTime, pendingIntent);但是需要注意的是从api 19开始,所有的周期性闹钟都不是精确响应的。 如果想要实现精确的周期性响应,那么应该使用单次精确闹钟,然后递归调用从而间接实现。 5、adb查看闹钟信息在调试闹钟时,我们可以通过如下命令打印闹钟信息来调试逻辑。 adb shell dumpsys alarm 该命令可以打出很多有用的信息。 但是信息中的字段说明在google官方文档中没有说明。 可以参考此篇在stackoverflow上的回答。 里面有比较详细的字段解释。 该命令打印的内容一般比较多,可以考虑将内容输出到文本文件,然后通过搜索包名查找相应的内容。 ‘ 6、triggerAtMillis参数问题不论单次还是周期性闹钟,对应的方法中都有一个触发时间的参数,也即triggerAtMillis。我遇到有的项目传0的情况,之前很好奇传0是啥效果。看接口的文档说明是如果传一个过去的时间,那么闹钟会立刻响应(实际上这个立刻也没很快,实测每次时间都不等,有长有短)。 有了上面的adb查看闹钟信息后,通过如下demo来验证一下不同triggertime的表现。 但是在多次的测试中发现,大部份情况下,下一次的响应时间能够回到正确的未来时间。但偶尔也会出现不符合常理的现像。 如当前时间是2020年1月10日22点07分,那么下一次的时间是超过当前时间且当前时间是隔间5分钟的整数倍的最小时间值, 为2020年1月10日22点10分,下下次的响应时间就是22点15分,依此类推。 但是,在某些情况下也会出现,响应了第一次的闹钟后,还未到下一次响应时间前又响应了一次。 如下: 通过adb shell dumpsys alarm命令发现,设备重启后应用之前设置的闹钟服务是会被清掉的。 这一点需要注意。 这让我想到了闹钟应用的实现。 如果重启闹钟会被清掉,那么闹钟应用是怎么实现的呢?带着好奇,我粗略的阅读了一下google的时钟应用源码。 首先,闹钟应用会监听设备开机广播,如下: 1、闹钟在api 19及以后都是不精确的响应的。 2、闹钟类型中的RTC_WAKEUP及RTC的差别在于是否会唤醒设备cpu,但android设备灭屏后不一定马上进入休眠,这个过程是android底层控制的。 同理与ELAPSED_REALTIME_WAKEUP与ELAPSED_REALTIME。 3、精确类型的闹钟可以通过单次精确闹钟递归调用间接实现。 4、triggerAtMillis尽量避免传入0,可用System.currentTimeMillis()或SystemClock.elapsedRealtime()来代替。 5、设备重启后之前设置的闹钟会被清掉,如果有需要,则要重新调置。 6、闹钟可用adb shell dumpsys alarm命令来调试。 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |