随时随地技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(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源码解析相关推荐

  1. AsyncTask、HandlerThread、IntentSerivce源码解析

    在进行耗时操作时,一般new Thread().start();开启一个子线程,然后通过handler消息去更新ui(关于handler可以看这里:android Handler.Looper.Mes ...

  2. 谷歌BERT预训练源码解析(二):模型构建

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_39470744/arti ...

  3. 谷歌BERT预训练源码解析(三):训练过程

    目录 前言 源码解析 主函数 自定义模型 遮蔽词预测 下一句预测 规范化数据集 前言 本部分介绍BERT训练过程,BERT模型训练过程是在自己的TPU上进行的,这部分我没做过研究所以不做深入探讨.BE ...

  4. 谷歌BERT预训练源码解析(一):训练数据生成

    目录 预训练源码结构简介 输入输出 源码解析 参数 主函数 创建训练实例 下一句预测&实例生成 随机遮蔽 输出 结果一览 预训练源码结构简介 关于BERT,简单来说,它是一个基于Transfo ...

  5. Gin源码解析和例子——中间件(middleware)

    在<Gin源码解析和例子--路由>一文中,我们已经初识中间件.本文将继续探讨这个技术.(转载请指明出于breaksoftware的csdn博客) Gin的中间件,本质是一个匿名回调函数.这 ...

  6. Colly源码解析——结合例子分析底层实现

    通过<Colly源码解析--框架>分析,我们可以知道Colly执行的主要流程.本文将结合http://go-colly.org上的例子分析一些高级设置的底层实现.(转载请指明出于break ...

  7. libev源码解析——定时器监视器和组织形式

    我们先看下定时器监视器的数据结构.(转载请指明出于breaksoftware的csdn博客) /* invoked after a specific time, repeatable (based o ...

  8. libev源码解析——定时器原理

    本文将回答<libev源码解析--I/O模型>中抛出的两个问题.(转载请指明出于breaksoftware的csdn博客) 对于问题1:为什么backend_poll函数需要指定超时?我们 ...

  9. libev源码解析——I/O模型

    在<libev源码解析--总览>一文中,我们介绍过,libev是一个基于事件的循环库.本文将介绍其和事件及循环之间的关系.(转载请指明出于breaksoftware的csdn博客) 目前i ...

最新文章

  1. Activity具体解释(生命周期、以各种方式启动Activity、状态保存,全然退出等)...
  2. PostgreSQL在何处处理 sql查询之五十二
  3. hdu4560 不错的建图,二分最大流
  4. 107条javascript常用小技巧
  5. 【CentOS 7】 yum源安装mysql5.6
  6. Android通过XML来定义Menu
  7. CF1237F Balanced Domino Placements(组合计数,dp)
  8. (C/C++学习笔记) 十二. 指针
  9. 喜庆新年春节 祝贺语词 艺术字体PSD分层素材
  10. Prometheus-普罗米修斯:高扩展性的监控和报警系统
  11. 命令行打印二维码-pyqrcode
  12. 计算机导论的计算题,计算机导论复习题(选择部分)汇总
  13. weblogic错误页面
  14. 颜色的前世今生10·HSB拾色器详解
  15. Take Your Seat
  16. 思考(六十四):游戏中的角色ID问题
  17. 《大话数据结构》总结一下
  18. 如何将eml格式转换成word文档
  19. docker 搭建frp内网穿透以及frp详细使用
  20. win7桌面不显示我的计算机名,win7系统桌面没有显示我的电脑图标的操作技巧

热门文章

  1. html注册邮箱格式正则表达式代码,jquery 验证Email邮箱格式的几个例子
  2. 前端面试题+答案(Vue篇)
  3. 21点小游戏java编程_用Java编写一个二十一点小游戏
  4. 花果职测指南针-事业单位职测高分必修课
  5. 私有化部署GPT,告别网络困扰
  6. 20M的Wi-Fi能用百兆宽带?给大家科普下
  7. C/C++中 sizeof 详解
  8. DrawText的使用
  9. 实验一:基于Ubuntu系统实现无人机自主飞行
  10. 获取select2选中的值_传奇技能第二祭:获取GM权限及管理员命令,调爆率和刷怪...