云题海 - 专业文章范例文档资料分享平台

当前位置:首页 > Android6.0 设备Idle状态(二)AlarmManagerService setIdleUntil接口

Android6.0 设备Idle状态(二)AlarmManagerService setIdleUntil接口

  • 62 次阅读
  • 3 次下载
  • 2025/12/29 1:28:17

Android6.0 设备Idle状态(二)AlarmManagerService setIdleUntil接口

一、set接口对flag中带了FLAG_IDLE_UNTIL的Alarm处理 先来看AlarmManager中:

[java] view plain copy 在CODE上查看代码片派生到我的代码片

public void setIdleUntil(int type, long triggerAtMillis, PendingIntent operation) {

setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, FLAG_IDLE_UNTIL, operation, null, null); }

这个接口就是在flag中带了FLAG_IDLE_UNTIL。 我们再来看下AlarmManagerService中的set函数:

[java] view plain copy 在CODE上查看代码片派生到我的代码片 private final IBinder mService = new IAlarmManager.Stub() { @Override

public void set(int type, long triggerAtTime, long windowLength, long interval, int flags, PendingIntent operation, WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock) { final int callingUid = Binder.getCallingUid(); if (workSource != null) {

getContext().enforcePermission(

android.Manifest.permission.UPDATE_DEVICE_STATS, Binder.getCallingPid(), callingUid, \ }

// No incoming callers can request either WAKE_FROM_IDLE or

// ALLOW_WHILE_IDLE_UNRESTRICTED -- we will apply those later as appropriate.

flags &= ~(AlarmManager.FLAG_WAKE_FROM_IDLE

| AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED);

// Only the system can use FLAG_IDLE_UNTIL -- this is used to tell the alarm // manager when to come out of idle mode, which is only for DeviceIdleController. if (callingUid != Process.SYSTEM_UID) {//如果不是系统应用不能拥有该flag flags &= ~AlarmManager.FLAG_IDLE_UNTIL; }

不是系统应用不能应有该flag。注释的说明也是这个flag只给DeviceIdleController用。

二、setImplLocked函数

继续分析setImplLocked函数

[java] view plain copy 在CODE上查看代码片派生到我的代码片

private void setImplLocked(Alarm a, boolean rebatching, boolean doValidate) { if ((a.flags&AlarmManager.FLAG_IDLE_UNTIL) != 0) {//是该flag

// This is a special alarm that will put the system into idle until it goes off. // The caller has given the time they want this to happen at, however we need // to pull that earlier if there are existing alarms that have requested to // bring us out of idle.

if (mNextWakeFromIdle != null) {//第一次该值为null a.when = a.whenElapsed = a.maxWhenElapsed = mNextWakeFromIdle.whenElapsed; }

// Add fuzz to make the alarm go off some time before the actual desired time. final long nowElapsed = SystemClock.elapsedRealtime();

final int fuzz = fuzzForDuration(a.whenElapsed-nowElapsed);// 调整时间 if (fuzz > 0) {

if (mRandom == null) {

mRandom = new Random(); }

final int delta = mRandom.nextInt(fuzz); a.whenElapsed -= delta;//调整时间 if (false) {

Slog.d(TAG, \

Slog.d(TAG, \ Slog.d(TAG, \ Slog.d(TAG, \

Slog.d(TAG, \ }

a.when = a.maxWhenElapsed = a.whenElapsed; }

} else if (mPendingIdleUntil != null) {

// We currently have an idle until alarm scheduled; if the new alarm has // not explicitly stated it wants to run while idle, then put it on hold. if ((a.flags&(AlarmManager.FLAG_ALLOW_WHILE_IDLE

| AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED | AlarmManager.FLAG_WAKE_FROM_IDLE)) == 0) {

mPendingWhileIdleAlarms.add(a); return; } }

int whichBatch = ((a.flags&AlarmManager.FLAG_STANDALONE) != 0)//这块和以前一样没改动

? -1 : attemptCoalesceLocked(a.whenElapsed, a.maxWhenElapsed); if (whichBatch < 0) {

Batch batch = new Batch(a);

addBatchLocked(mAlarmBatches, batch); } else {

Batch batch = mAlarmBatches.get(whichBatch); if (batch.add(a)) {

// The start time of this batch advanced, so batch ordering may // have just been broken. Move it to where it now belongs. mAlarmBatches.remove(whichBatch); addBatchLocked(mAlarmBatches, batch); } }

if (a.alarmClock != null) {

mNextAlarmClockMayChange = true; }

boolean needRebatch = false;

if ((a.flags&AlarmManager.FLAG_IDLE_UNTIL) != 0) {

mPendingIdleUntil = a;//如果又改flag的alarm,设置mPendingIdleUntil mConstants.updateAllowWhileIdleMinTimeLocked(); needRebatch = true;// 需要rebatch

} else if ((a.flags&AlarmManager.FLAG_WAKE_FROM_IDLE) != 0) {

if (mNextWakeFromIdle == null || mNextWakeFromIdle.whenElapsed > a.whenElapsed) {

mNextWakeFromIdle = a;

// If this wake from idle is earlier than whatever was previously scheduled, // and we are currently idling, then we need to rebatch alarms in case the idle // until time needs to be updated. if (mPendingIdleUntil != null) { needRebatch = true; } } }

if (!rebatching) {

if (DEBUG_VALIDATE) {

if (doValidate && !validateConsistencyLocked()) {

Slog.v(TAG, \ + \ + \

+ \

+ \ + \ rebatchAllAlarmsLocked(false);

needRebatch = false; } }

if (needRebatch) {

rebatchAllAlarmsLocked(false);//rebatch }

rescheduleKernelAlarmsLocked(); updateNextAlarmClockLocked(); } }

我们先看fuzzForDuration函数:

[java] view plain copy 在CODE上查看代码片派生到我的代码片 static int fuzzForDuration(long duration) {

if (duration < 15*60*1000) {// 小于15分钟

// If the duration until the time is less than 15 minutes, the maximum fuzz // is the duration. return (int)duration;

} else if (duration < 90*60*1000) {//小于90分钟

// If duration is less than 1 1/2 hours, the maximum fuzz is 15 minutes, return 15*60*1000; } else {

// Otherwise, we will fuzz by at most half an hour. return 30*60*1000;//最多半小时 } }

所以上面如果有该flag的alarm,设置下来,需要重新rebatch所有的alarm。

再来看下rebatchAllAlarmsLocked函数

[java] view plain copy 在CODE上查看代码片派生到我的代码片 void rebatchAllAlarmsLocked(boolean doValidate) {

ArrayList oldSet = (ArrayList) mAlarmBatches.clone(); mAlarmBatches.clear();

Alarm oldPendingIdleUntil = mPendingIdleUntil;

final long nowElapsed = SystemClock.elapsedRealtime(); final int oldBatches = oldSet.size();

for (int batchNum = 0; batchNum < oldBatches; batchNum++) {//遍历所有的batch Batch batch = oldSet.get(batchNum); final int N = batch.size(); for (int i = 0; i < N; i++) {

reAddAlarmLocked(batch.get(i), nowElapsed, doValidate);// 遍历所有的batch中的alarm重新设置 }

搜索更多关于: Android6.0 设备Idle状态(二)AlarmMan 的文档
  • 收藏
  • 违规举报
  • 版权认领
下载文档10.00 元 加入VIP免费下载
推荐下载
本文作者:...

共分享92篇相关文档

文档简介:

Android6.0 设备Idle状态(二)AlarmManagerService setIdleUntil接口 一、set接口对flag中带了FLAG_IDLE_UNTIL的Alarm处理 先来看AlarmManager中: [java] view plain copy 在CODE上查看代码片派生到我的代码片 public void setIdleUntil(int type, long triggerAtMillis, PendingIntent operation) { setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, FLAG_IDLE_UNTIL, operation, null, null); } 这个接口就是在flag中带了FLAG_I

× 游客快捷下载通道(下载后可以自由复制和排版)
单篇付费下载
限时特价:10 元/份 原价:20元
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:fanwen365 QQ:370150219
Copyright © 云题海 All Rights Reserved. 苏ICP备16052595号-3 网站地图 客服QQ:370150219 邮箱:370150219@qq.com