PowerManager的用法分析

来源:互联网 发布:人工蜂群算法流程图 编辑:程序博客网 时间:2024/05/20 22:28

在分析PMS的工作原理之前,我们先来分析下PowerManager的用法

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);  PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag");  wl.acquire();    ..screen will stay on during this section..      wl.release()

从以上代码中我们可以看出WakeLock用法的关键点

1.new 一个WakeLock对象,同时传入该WakeLock的类型的Flag标志

2.在使用之前调用wakeLock.aquire()获取锁

3.在使用之后调用wakeLock.release()释放锁

WakeLock是Android系统提供给应用程序获取电力资源的方法,只要有应用还在使用WakeLock,系统就不会进入休眠状态。

系统中已经定义看一些wakeLock类型,wakeLock一般只会影响cpu,屏幕和键盘灯三大模块

1. PARTIAL_WAKE_LOCK :cpu一直保持运行,允许屏幕和键盘灯熄灭

2. SCREEN_DIM_WAKE_LOCK :cpu保持运行,屏幕变暗,允许键盘灯熄灭

3. SCREEN_BRIGHT_WAKE_LOCK :cpu保持运行,屏幕亮屏,允许键盘灯熄灭

4. FULL_WAKE_LOCK : cpu保持运行,屏幕和键盘灯点亮

除了以上的4中wakeLock外,还有两种附件的wakeLock类型,这两种类型需要和以上4中组合使用,但是partial wakelock比较特殊,附件wakelock不影响他的状态

1. ACQUIRE_CAUSES_WAKEUP : 和其他wakeLock组合使用,表示申请wakeLock的同时是否唤醒屏幕

2. ON_AFTER_RELEASE :和其他wakeLock组合使用,释放wakeLock后不会立即熄灭屏幕,延迟一段时间在熄灭,和用户体验有关

我们知道PowerManager和PowerManagerService之间的关系,PowerManagerService作为服务端,而PowerManager则为客户端的代理,他们之间通过binder进行进程间通信。

wakeLock.aquire分析

aquire()方法最终调用PMS的aquireWakeLock()方法,该方法中检查并申请相关的权限,最终由aquireWakeLockInternal()方法来处理。

private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,            WorkSource ws, String historyTag, int uid, int pid) {        synchronized (mLock) {            WakeLock wakeLock;            //查找wakelock是否存在            int index = findWakeLockIndexLocked(lock);            boolean notifyAcquire;            if (index >= 0) {                //存在,从列表中获取该wakeLock                wakeLock = mWakeLocks.get(index);                //wakelock属性发生了变化,在更新该属性                if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {                    notifyWakeLockChangingLocked(wakeLock, flags, tag, packageName,                            uid, pid, ws, historyTag);                    wakeLock.updateProperties(flags, tag, packageName, ws, historyTag, uid, pid);                }                notifyAcquire = false;            } else {                //不存在,创建一个新的wakelock                wakeLock = new WakeLock(lock, flags, tag, packageName, ws, historyTag, uid, pid);                try {                    lock.linkToDeath(wakeLock, 0);                } catch (RemoteException ex) {                    throw new IllegalArgumentException("Wake lock is already dead.");                }                //添加到wakelock列表                mWakeLocks.add(wakeLock);                //根据Doze模式的白名单更新wakelock的disabled变量                setWakeLockDisabledStateLocked(wakeLock);                notifyAcquire = true;            }            //查看wakeLock是否有ACQUIRE_CAUSES_WAKEUP标志,有的话唤醒屏幕            applyWakeLockFlagsOnAcquireLocked(wakeLock, uid);            mDirty |= DIRTY_WAKE_LOCKS;            //更新电源信息            updatePowerStateLocked();            if (notifyAcquire) {                //通知wakeLock发生变化                //电量统计服务做相关统计                notifyWakeLockAcquiredLocked(wakeLock);            }        }    }

Aquire方法的具体流程


AAA



WakeLock.release方法

同样该方法最终调用PMS的releaseWakeLock方法,该方法检查和申请权限,最终由releaseWakeLockInternal()方法处理

该方法中首先判断wakeLock是否存在,若存在,则获取对应的wakeLock对象,从wakeLock列表中移除

下面是release方法流程图

BBBB



wakeup方法

强制将设备从Sleep状态唤醒,比如按Power键点亮屏幕

该方法最终调用PMS的wakeUpInternal()方法

private void wakeUpInternal(long eventTime, String reason, int uid, String opPackageName,            int opUid) {        synchronized (mLock) {            if (wakeUpNoUpdateLocked(eventTime, reason, uid, opPackageName, opUid)) {                updatePowerStateLocked();            }        }    }

该方法根据wakeUpNoUpdateLocked方法进行判断,如果为true

则调用更新电源状态信息

PMS类中有很多***NoUpdateLocked()方法,这些方法都有一些共性,就是更新状态,不负责体的执行,因为具体的执行逻辑都是在updatePowerStateLocked方法中。

那么我们在来看下wakeUpNoUpdateLocked方法的实现

 private boolean wakeUpNoUpdateLocked(long eventTime, String reason, int reasonUid,            String opPackageName, int opUid) {        系统没有启动完成或者没有准备好,事件的时间不正确,当前已经是AWAKE        不处理        if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE                || !mBootCompleted || !mSystemReady) {            return false;        }        try {            更新mLastWakeTime时间            mLastWakeTime = eventTime;            //修改当前的状态mWakefulness为WAKEFULNESS_AWAKE            setWakefulnessLocked(WAKEFULNESS_AWAKE, 0);            通知发生了变化            mNotifier.onWakeUp(reason, reasonUid, opPackageName, opUid);            触发一次用户活动            userActivityNoUpdateLocked(                    eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, reasonUid);        }        return true;    }

PowerManager的基本用法分析完成,下面我们来具体分析下PMS服务的工作原理



2 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 8个月了胎位不正怎么办 怀孕八个月了胎位不正怎么办 怀孕八个月胎位不正怎么办 欠债的人跑了怎么办 赌博输了100万怎么办 我赌博输了4万怎么办 办80张信用卡怎么办的 19岁负债十几万怎么办 欠了十几万该怎么办 网贷负债十几万怎么办 赌博欠了十几万怎么办 欠了网贷跑了会怎么办 欠银行钱还不起怎么办 欠小额贷款公司的钱还不上怎么办 负债30万没工作怎么办 华为p9耗电太快怎么办 酷派手机反应慢怎么办 网上买手机被骗了怎么办 买手机贵了怎么办12315 在手机店被骗了怎么办 在转转上被骗了怎么办 微信被骗了800怎么办 苹果6被偷走该怎么办 苹果7被偷走该怎么办 月经量突然少了怎么办 我月经老是不来怎么办 月经不来3个月怎么办 月经推迟3个月怎么办 乙肝五项25阳怎么办 乙肝五项25阳性怎么办 流浓鼻涕怎么办速效办法 鼻涕又浓又黄绿怎么办 玉露已经徒长了怎么办 多肉长出了多头怎么办 多肉已经徒长了怎么办 脖子抻筋了 很疼怎么办 声带肥大造成说话声音沙哑怎么办 轻微的骨性龅牙怎么办 19岁没了晨勃怎么办 早上晨勃消失了怎么办 阴茎勃而不坚怎么办