PowerManager的用法分析
2016-09-08 19:58
274 查看
在分析PMS的工作原理之前,我们先来分析下PowerManager的用法
从以上代码中我们可以看出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进行进程间通信。
Aquire方法的具体流程
该方法中首先判断wakeLock是否存在,若存在,则获取对应的wakeLock对象,从wakeLock列表中移除
下面是release方法流程图
该方法最终调用PMS的wakeUpInternal()方法
该方法根据wakeUpNoUpdateLocked方法进行判断,如果为true
则调用更新电源状态信息
PMS类中有很多***NoUpdateLocked()方法,这些方法都有一些共性,就是更新状态,不负责体的执行,因为具体的执行逻辑都是在updatePowerStateLocked方法中。
那么我们在来看下wakeUpNoUpdateLocked方法的实现
PowerManager的基本用法分析完成,下面我们来具体分析下PMS服务的工作原理
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方法的具体流程
WakeLock.release方法
同样该方法最终调用PMS的releaseWakeLock方法,该方法检查和申请权限,最终由releaseWakeLockInternal()方法处理该方法中首先判断wakeLock是否存在,若存在,则获取对应的wakeLock对象,从wakeLock列表中移除
下面是release方法流程图
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服务的工作原理
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories