PowerManager之WakeLock源码解析
来源:互联网 发布:蜀道难 知乎 编辑:程序博客网 时间:2024/05/20 09:08
首先看源码注释里对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,用来控制在某个页面保持屏幕恒亮。
0 0
- PowerManager之WakeLock源码解析
- PowerManager.WakeLock源码解读
- PowerManager.WakeLock源码解读
- PowerManager之WakeLock
- Android电源管理之三:PowerManager.WakeLock源码详读
- android API之PowerManager和PowerManager.WakeLock
- PowerManager.WakeLock源码解读(By DADA)
- PowerManager WakeLock
- PowerManager.WakeLock
- PowerManager.WakeLock
- PowerManager.WakeLock
- PowerManager.WakeLock
- PowerManager.WakeLock
- PowerManager和PowerManager.WakeLock
- PowerManager和PowerManager.WakeLock
- PowerManager和PowerManager.WakeLock详解
- Android: PowerManager.WakeLock
- android PowerManager wakelock
- 用jquery制作导航定位特效
- java动态规划 实现输出最大公共子序列的长度以及输出最大子字符串
- hive 开机重启 mysql
- Github GUI 基本操作教程
- 【Demo】iOS可吸附拖动的悬浮窗按钮插件
- PowerManager之WakeLock源码解析
- 操作系统实验四 页面置换算法(fifo 算法代码------页面置换代码集合)
- VS2005 ~ VS2010 中宏不能运行的解决办法
- c语言学习笔记27之指针3
- php中引用&的真正理解-变量引用、函数引用、对象引用
- 跨进程数据共享问题及解决方案
- Spark Streaming的Transformation、Action、Input和Output源码图解(第24课)
- 考研复习第1弹
- char[] 与 char*传字符串的区别