24 AlarmManagerService机制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了24 AlarmManagerService机制相关的知识,希望对你有一定的参考价值。
参考技术A 上一篇文章JobScheduler机制, 介绍了根据一定条件而触发的任务可以采用JobScheduler. 那么对于只是定时的任务, 而非考虑网络/时间之类的条件,也可以直接采用AlarmManager来完成.AlarmManager的用法
对于alarmManager关于alarm的类型, 以及时间到达后可以选择发送广播, 启动Activity或许启动服务等自由组合.
[-> SystemServer.java]
AlarmManagerService的初始化比JobScheduler更早。
[-> AlarmManagerService.java]
此处AlarmHandler mHandler = new AlarmHandler(),该Handler运行在system_server的主线程。
[-> AlarmManagerService.java ::Constants]
当系统处于idle状态,则alarm最小时间间隔为9min;当处于非idle则最小时间间隔为5s.
[-> AlarmManagerService.java]
该方法主要功能:
[-> com_android_server_AlarmManagerService.cpp]
打开节点/dev/alarm,并创建Alarm驱动对象。
此处android_alarm_to_clockid数组如下:
此处创建AlarmImplTimerFd
[-> AlarmManagerService.java ::ClockReceiver]
注册用于监听TIME_TICK和DATE_CHANGED的广播。
[-> AlarmManagerService.java ::ClockReceiver]
[-> AlarmManagerService.java]
再来看看”AlarmManager”线程的工作过程.
[-> AlarmManagerService.java ::AlarmThread]
[-> com_android_server_AlarmManagerService.cpp]
alarm使用过程会使用到PendingIntent,先来简单介绍下PendingIntent.
常见PendingIntent常见的几个静态方法如下:
以上3个方法最终都会调用到AMS.getIntentSender,主要的不同在于第一个参数 TYPE .
[-> PendingIntent.java]
getIntentSender()获取的是PendingIntentRecord对象, 而该对象继承于IIntentSender.Stub, 经过binder call回来, 所以此处target是指PendingIntentRecord对象的代理端, 即为PendingIntent.mTarget.
此处packageName为设置PendingIntent所在进程的包名, 后续会把该信息保存到PendingIntentRecord.Key.
由此可知,getSystemService(Service.ALARM_SERVICE)获取的是AlarmManager对象,再来看看其创建过程。
[-> AlarmManager.java]
此处mMainThreadHandler是运行在app进程的主线程。
[-> AlarmManager.java]
[-> AlarmManager.java]
注意: 此处targetHandler这个是在Android N上才有的逻辑. 此处mService是指远程IAlarmManager的代理类, 服务类位于ALMS的成员变量mService = new IAlarmManager.Stub()。 可见,接下来程序运行到system_server进程。
由[]小节2.8] 可知当alarm时间触发时则执行deliverAlarmsLocked(), 接下来,从该方法说起.
[-> AlarmManagerService.java]
[-> AlarmManagerService.java]
[-> PendingIntent.java]
由小节3.1, 可知mTarget代表的是远端PendingIntentRecord对象. 可知接下来进入到system_server的如下方法.
[-> pendingIntentRecord.java]
[-> pendingIntentRecord.java]
可见,
再回到小节4.2 deliverLocked,可知当没有指定PendingIntent时,则会回调listener的doAlarm()过程. 由[小节3.4]创建的ListenerWrapper对象.
[-> AlarmManager.java ::ListenerWrapper]
默认情况下mHandler是指设置闹钟setImpl方法所在进程的主线程, 当然也可以指定Handler线程. 对于前面 JobSchedulerService 中用到的TimeController 则是在system_server进程设置的闹钟, 那么接下来post到了system_server的主线程.
这里以TimeController为例, 可知接下来,便会进入mNextDelayExpiredListener.onAlarm()的过程
[-> TimeController.java]
此处没有指定handler, 则onAlarm回调方法默认运行在system_server的主线程.
设置闹钟有3种类型:
Type有4种类型:
以上是关于24 AlarmManagerService机制的主要内容,如果未能解决你的问题,请参考以下文章