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机制的主要内容,如果未能解决你的问题,请参考以下文章

本地通知崩溃应用程序android java

alarmManager关机再开机后还有效吗

类的加载机制

Wildfly 24 中带有 Elytron 的多个 sasl 身份验证机制

Pytest权威教程24-Pytest导入机制及系统路径

深入探讨 Python 的 import 机制:实现远程导入模块