PowerManager之PowerManager

2018-04-04 23:52:03

1.何时需要使用WakeLock?

A wake lock is a mechanism to indicate that your application needs to have the device stay on.

当你在做一些事情时,如果持续时间过长,那么一段时间后屏幕会灭掉,如果你想在你做这些事时屏幕始终保持点亮状态,那么你需要WakeLock的帮助。

比如:视频播放器在播放视频过程中,一段时间无操作后就会休眠灭屏,那么用户就需要每隔一段时间就去做类似触摸屏幕的操作来保持屏幕常亮,用户是不会接受这样的视频播放器,那么你就需要WakeLock啦。


2.如何使用WakeLock?

sample code:


[java] view plain copy

  1. PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);  

  2. PowerManager.WakeLock wl = pm.newWakeLock(  

  3.                                      PowerManager.SCREEN_DIM_WAKE_LOCK  

  4.                                      | PowerManager.ON_AFTER_RELEASE,  

  5.                                      TAG);  

  6. wl.acquire();  

  7. // ... do work...  

  8. wl.release();  

  9. }  

Any application using a WakeLock must request the android.permission.WAKE_LOCK permission--需要在AndroidManifest.xml中声明使用这个permission。


使用过程:首先创建实例,然后acquire保持屏幕点亮,然后做你的事情,做完后,一定要release,这样屏幕会在合适的时候熄灭,这对电池的续航很重要。


3.关于newWakeLock方法

Creates a new wake lock with the specified level and flags--创建实例,但同时指明了WakeLock的级别和flag。


[java] view plain copy

  1. public WakeLock newWakeLock(int levelAndFlags, String tag) {  

  2.     validateWakeLockParameters(levelAndFlags, tag);  

  3.     return new WakeLock(levelAndFlags, tag);  

  4. }  

首先讨论级别:


一共有五个级别,对应用可见的只有四个级别。


[java] view plain copy

  1. public static final int PARTIAL_WAKE_LOCK = 0x00000001;  

  2. public static final int SCREEN_DIM_WAKE_LOCK = 0x00000006;  

  3. public static final int SCREEN_BRIGHT_WAKE_LOCK = 0x0000000a;  

  4. public static final int FULL_WAKE_LOCK = 0x0000001a;  

  5. {@hide}  

  6. public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 0x00000020;  

  7. public static final int WAKE_LOCK_LEVEL_MASK = 0x0000ffff;  

Exactly one wake lock level must be specified as part of the {@code levelAndFlags} parameter.
在newWakeLock时,必须指定级别,否则会抛出异常信息:throw new IllegalArgumentException("Must specify a valid wake lock level.");


这几个级别之间的差别,留在后面分析,这里先跳过。

Flag只有两种:


[java] view plain copy

  1. //Turn the screen on when the wake lock is acquired.  

  2. public static final int ACQUIRE_CAUSES_WAKEUP = 0x10000000;  

  3. //When this wake lock is released, poke the user activity timer so the screen stays on for a little longer.  

  4. public static final int ON_AFTER_RELEASE = 0x20000000;  

ACQUIRE_CAUSES_WAKEUP:


一般地,WakeLock并不会真的唤醒设备,它的作用只是在屏幕是亮的状态下保持这种亮的状态。但是有时我们需要它能不仅仅是保持亮,还能把它从灭唤醒,那么就需要这个flag:在acquired时,它会唤醒屏幕。

ON_AFTER_RELEASE:

在release时,它会重置timeout,这样能让屏幕保持亮的状态稍久一些。当然,如果已经灭了,它也不能在唤醒屏幕。


level和flag可以一起使用,但是PARTIAL_WAKE_LOCK是个例外,如果是这个level,那么不能使用这两个flag(备注:如果你这样使用了并不会报错,只是这两个flag不会起作用,会被忽略)。

留意WAKE_LOCK_LEVEL_MASK,它的作用很清楚:既然level和flag可以一起使用,那么就规定level之占用较低的两个字节,flag则使用较高的两个字节。


4.关于acquire和release

这是一对操作,一般地,调用多少次acquire,就要相应地调用相同次数的release:

如果acquire多于release,那么屏幕会一直保持点亮的状态;

如果release多于acuire,那么会抛出异常:throw new RuntimeException("WakeLock under-locked " + mTag);

WakeLock中有个变量mCount负责记录,当acquire时增一,release时减一。

实际的操作还是由PowerManagerService的acquireWakeLock和releaseWakeLock方法来实现。


public void acquire(long timeout)

acquire的这个方法允许传人一个参数,那么在timeout时间之后,会自动调用release一次。


public void setReferenceCounted(boolean value)

这个方法的作用(默认value为true,可以通过此方法将其设置为false):若为false,则不管之前调用了多少次acquire,一次release就ok啦。


5.关于level的讨论

这是SDK中的一张图,从这张图我们可以看到WakeLock控制了哪些器件:CPU、Screen和Keyboard。


看起来,似乎FULL_WAKE_LOCK最强大,它保持三个器件都处于on或bright的状态,但请注意,如果用户按下power键使手机进入sleep状态时,这三个器件将都不再on或bright,都会进入休眠状态。

而PARTIAL_WAKE_LOCK是比较特别的,它的on上打了个*标记:即使用户按下power键使手机进入sleep状态,如果持有这个level的WakeLock,那么CPU也会一直处于on的状态,直到它被释放,也就是在这个level下,用户是无法使CPU off的。相比其它三个level,用户可以在任何时候使他们处于off状态。


  • 2020-01-13 21:56:45

    Ant Design Pro nginx配置

    Ant Design Pro nginx配置 今天看了下Ant和nginx的配置 给大家分享下 下边的配置可以直接使用 修改为自己的域名和文件夹目录就可以

  • 2020-01-13 23:36:35

    webpack之externals详解(精华)

    官网文档解释的很清楚,就是webpack可以不处理应用的某些依赖库,使用externals配置后,依旧可以在代码中通过CMD、AMD或者window/global全局的方式访问。

  • 2020-01-14 00:12:22

    webpack externals详解

    在众多的webpack配置教程中,对externals这个配置选项,总是一带而过,把文档中提到的几种方式都复述一遍,但是对于开发者而言,根本没法完全理解。本文试图通过一整篇文章,详细的对externals这个参数进行讲解。

  • 2020-01-14 01:06:37

    webpack externals 深入理解

    按照官方文档的解释,如果我们想引用一个库,但是又不想让webpack打包,并且又不影响我们在程序中以CMD、AMD或者window/global全局等方式进行使用,那就可以通过配置externals。这个功能主要是用在创建一个库的时候用的,但是也可以在我们项目开发中充分使用。

  • 2020-01-14 01:08:19

    webpack用externals优化echarts

    防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies)。