PowerManager之WakeLock源码解析
随时随地技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(ydmsq666)
首先看源码注释里对WakeLock类的注释:
/*** A wake lock is a mechanism to indicate that your application needs* to have the device stay on.* <p>* Any application using a WakeLock must request the {@code android.permission.WAKE_LOCK}* permission in an {@code <uses-permission>} element of the application's manifest.* Obtain a wake lock by calling {@link PowerManager#newWakeLock(int, String)}.* </p><p>* Call {@link #acquire()} to acquire the wake lock and force the device to stay* on at the level that was requested when the wake lock was created.* </p><p>* Call {@link #release()} when you are done and don't need the lock anymore.* It is very important to do this as soon as possible to avoid running down the* device's battery excessively.* </p>*/
用来控制设备保持运行状态的,需要配置申请权限,获取实例通过newWakeLock方法、使用acquire获取唤醒锁保持设备运行、使用release进行释放
加锁方式有两种,一种为永久锁,需要用户手动释放,另一种是超时锁,到时间后自动释放,源码如下
/*** Acquires the wake lock.* <p>* Ensures that the device is on at the level requested when* the wake lock was created.* </p>*/public void acquire() {synchronized (mToken) {acquireLocked();}}
/*** Acquires the wake lock with a timeout.* <p>* Ensures that the device is on at the level requested when* the wake lock was created. The lock will be released after the given timeout* expires.* </p>** @param timeout The timeout after which to release the wake lock, in milliseconds.*/public void acquire(long timeout) {synchronized (mToken) {acquireLocked();mHandler.postDelayed(mReleaser, timeout);}}
mReleaser是释放锁的Runnable
private final Runnable mReleaser = new Runnable() {public void run() {release();}};
再回到前面看加锁的源码acquireLocked:
private void acquireLocked() {if (!mRefCounted || mCount++ == 0) {// Do this even if the wake lock is already thought to be held (mHeld == true)// because non-reference counted wake locks are not always properly released.// For example, the keyguard's wake lock might be forcibly released by the// power manager without the keyguard knowing. A subsequent call to acquire// should immediately acquire the wake lock once again despite never having// been explicitly released by the keyguard.mHandler.removeCallbacks(mReleaser);try {mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource);} catch (RemoteException e) {}mHeld = true;}}
mRefCounted是用来控制是否关联计数的变量,默认为true,如果设置为false则后面的计数变量mCount一直不会改变
private boolean mRefCounted = true;
下面来看释放锁的源码release
/*** Releases the wake lock.* <p>* This method releases your claim to the CPU or screen being on.* The screen may turn off shortly after you release the wake lock, or it may* not if there are other wake locks still held.* </p>*/public void release() {release(0);}
/*** Releases the wake lock with flags to modify the release behavior.* <p>* This method releases your claim to the CPU or screen being on.* The screen may turn off shortly after you release the wake lock, or it may* not if there are other wake locks still held.* </p>** @param flags Combination of flag values to modify the release behavior.* Currently only {@link #WAIT_FOR_PROXIMITY_NEGATIVE} is supported.** {@hide}*/public void release(int flags) {synchronized (mToken) {if (!mRefCounted || --mCount == 0) {mHandler.removeCallbacks(mReleaser);if (mHeld) {try {mService.releaseWakeLock(mToken, flags);} catch (RemoteException e) {}mHeld = false;}}if (mCount < 0) {throw new RuntimeException("WakeLock under-locked " + mTag);}}}
所以不计数模式,无论acquire多少次,只需调一次release就可以进行释放;而计数模式每调一次acquire,只是把计数变量值加1,释放时也需要--mCount == 0时才能释放,调用次数过多,导致mCount<0会throw new RuntimeException("WakeLock under-locked " + mTag);而不计数模式不会出现,因为mCount一直为初始值0
那设置计数模式的地方在哪里呢,看下面
/*** Sets whether this WakeLock is reference counted.* <p>* Wake locks are reference counted by default. If a wake lock is* reference counted, then each call to {@link #acquire()} must be* balanced by an equal number of calls to {@link #release()}. If a wake* lock is not reference counted, then one call to {@link #release()} is* sufficient to undo the effect of all previous calls to {@link #acquire()}.* </p>** @param value True to make the wake lock reference counted, false to* make the wake lock non-reference counted.*/public void setReferenceCounted(boolean value) {synchronized (mToken) {mRefCounted = value;}}
注释已经很详细了
在实际开发中,可以这样简单使用,设置为不计数模式,然后在onResume中acquire,在onPause中release,用来控制在某个页面保持屏幕恒亮。
PowerManager之WakeLock源码解析相关推荐
- AsyncTask、HandlerThread、IntentSerivce源码解析
在进行耗时操作时,一般new Thread().start();开启一个子线程,然后通过handler消息去更新ui(关于handler可以看这里:android Handler.Looper.Mes ...
- 谷歌BERT预训练源码解析(二):模型构建
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_39470744/arti ...
- 谷歌BERT预训练源码解析(三):训练过程
目录 前言 源码解析 主函数 自定义模型 遮蔽词预测 下一句预测 规范化数据集 前言 本部分介绍BERT训练过程,BERT模型训练过程是在自己的TPU上进行的,这部分我没做过研究所以不做深入探讨.BE ...
- 谷歌BERT预训练源码解析(一):训练数据生成
目录 预训练源码结构简介 输入输出 源码解析 参数 主函数 创建训练实例 下一句预测&实例生成 随机遮蔽 输出 结果一览 预训练源码结构简介 关于BERT,简单来说,它是一个基于Transfo ...
- Gin源码解析和例子——中间件(middleware)
在<Gin源码解析和例子--路由>一文中,我们已经初识中间件.本文将继续探讨这个技术.(转载请指明出于breaksoftware的csdn博客) Gin的中间件,本质是一个匿名回调函数.这 ...
- Colly源码解析——结合例子分析底层实现
通过<Colly源码解析--框架>分析,我们可以知道Colly执行的主要流程.本文将结合http://go-colly.org上的例子分析一些高级设置的底层实现.(转载请指明出于break ...
- libev源码解析——定时器监视器和组织形式
我们先看下定时器监视器的数据结构.(转载请指明出于breaksoftware的csdn博客) /* invoked after a specific time, repeatable (based o ...
- libev源码解析——定时器原理
本文将回答<libev源码解析--I/O模型>中抛出的两个问题.(转载请指明出于breaksoftware的csdn博客) 对于问题1:为什么backend_poll函数需要指定超时?我们 ...
- libev源码解析——I/O模型
在<libev源码解析--总览>一文中,我们介绍过,libev是一个基于事件的循环库.本文将介绍其和事件及循环之间的关系.(转载请指明出于breaksoftware的csdn博客) 目前i ...
最新文章
- Activity具体解释(生命周期、以各种方式启动Activity、状态保存,全然退出等)...
- PostgreSQL在何处处理 sql查询之五十二
- hdu4560 不错的建图,二分最大流
- 107条javascript常用小技巧
- 【CentOS 7】 yum源安装mysql5.6
- Android通过XML来定义Menu
- CF1237F Balanced Domino Placements(组合计数,dp)
- (C/C++学习笔记) 十二. 指针
- 喜庆新年春节 祝贺语词 艺术字体PSD分层素材
- Prometheus-普罗米修斯:高扩展性的监控和报警系统
- 命令行打印二维码-pyqrcode
- 计算机导论的计算题,计算机导论复习题(选择部分)汇总
- weblogic错误页面
- 颜色的前世今生10·HSB拾色器详解
- Take Your Seat
- 思考(六十四):游戏中的角色ID问题
- 《大话数据结构》总结一下
- 如何将eml格式转换成word文档
- docker 搭建frp内网穿透以及frp详细使用
- win7桌面不显示我的计算机名,win7系统桌面没有显示我的电脑图标的操作技巧
热门文章
- html注册邮箱格式正则表达式代码,jquery 验证Email邮箱格式的几个例子
- 前端面试题+答案(Vue篇)
- 21点小游戏java编程_用Java编写一个二十一点小游戏
- 花果职测指南针-事业单位职测高分必修课
- 私有化部署GPT,告别网络困扰
- 20M的Wi-Fi能用百兆宽带?给大家科普下
- C/C++中 sizeof 详解
- DrawText的使用
- 实验一:基于Ubuntu系统实现无人机自主飞行
- 获取select2选中的值_传奇技能第二祭:获取GM权限及管理员命令,调爆率和刷怪...