300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > AlarmManager set 设置定时闹钟 延时执行的问题

AlarmManager set 设置定时闹钟 延时执行的问题

时间:2021-05-08 07:14:24

相关推荐

AlarmManager set 设置定时闹钟 延时执行的问题

背景:使用 AlarmManager 给系统设置定时关机,延时了1个多小时的才执行的问题

接到问题后,首先排查了代码,看到代码使用的是 Android 自带的 AlarmManager 设置一个服务的 PendingIntent,当时间到了,则执行关机程序。代码如下:

/*** 设置定时关机* @param time 多少ms后关机*/fun shutDownSystem(time: Long) {val intent = Intent(WebConfigApi.context,ShutdownService::class.java)val pendingIntent = PendingIntent.getService(context, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT)if (time <= 0) {alarm.cancel(pendingIntent)} else {alarm.set(AlarmManager.RTC_WAKEUP, time, pendingIntent)}}

从代码逻辑看,没啥问题。

一开始怀疑是客户设置了 ntp 服务,导致系统时间延时引起,但 ntp 只是为了校准时间,问了客户时间也是正常的。

从日志看,也不是必现的,所以写了一个定时开关机的脚本去压测,每次开机后对当前时间+5分钟,做定时开关机压测,测试了两天,都能开机关机。

从这里反应,程序应该是没问题,而且出货之前也测试过这块内容。

但从客户日志来,有一个跟脚本和测试明显的不同的区分,就是客户设置定时关机的跨度比较大,且设完一段时间未使用设备。

所以找了几个盒子,进行煲机,确实复现到了

但为啥时间跨度大,未使用设备就会出现?

说明软件程序确实有问题,跟踪进去,发现 set 方法,在 API 19,使用这个方法传递的时间视为不准确,系统为了减少电池消耗,可能会把这个 set 推迟,然后批量发送;

从这里可以看到,确实是set 这个方法引起的

所以,从源码出发,发现 setExact 这个方法,该方法指定系统在规定时间内发出,不允许系统调整交付时间。

修改后,问题解决。

思考:set 方法有问题,那可能标志位也有问题。可以发现 RTC_WAKEUP 标识使用的是 系统时间,也就是 System.currentTimeMillis(),这样设置的时间,容易被人修改;所以采用 ELAPSED_REALTIME_WAKEUP 这个标志位,它根据系统开机时间来计算,也就是 SystemClock.elapsedRealtime()。

所以,代码这里,关机的时间也需要改一下,从开机时间+设置的时间即可,如下:

/*** 设置定时关机* @param time 多少ms后关机*/fun shutDownSystem(time: Long) {val elapsedTime = SystemClock.elapsedRealtime()//开机时间 + 延时时间val alarmTime = elapsedTime + timeval intent = Intent(WebConfigApi.context,ShutdownService::class.java)val pendingIntent = PendingIntent.getService(context, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT)if (alarmTime <= 0) {alarm.cancel(pendingIntent)isDelayShutdown = false} else {//ELAPSED_REALTIME_WAKEUP 自开机其开始算时间,RTC_WAKEUP 则是根据系统时间有关// alarm.setExact()alarm.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmTime, pendingIntent)}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。