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状态。


  • 2018-12-08 11:44:26

    php 时间函数strtotime 使用详解

    这篇文章介绍的内容是关于php 时间函数strtotime 使用详解 ,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

  • 2018-12-09 15:52:37

    【Android - 进阶】之Animator属性动画

    在3.0系统之前,Android给我们提供了逐帧动画Frame Animation和补间动画Tween Animation两种动画: 逐帧动画的原理很简单,就是将一个完整的动画拆分成一张张单独的图片,然后将它们连贯起来进行播放; 补间动画是专门为View提供的动画,可以实现View的透明度、缩放、平移和旋转四种效果。

  • 2018-12-09 18:12:45

    显示软键盘,并让布局压缩

    博客 学院 下载 图文课 论坛 APP 问答 商城 VIP会员 活动 招聘 ITeye GitChat 搜博主文章 写博客传资源 原

  • 2018-12-09 22:48:14

    ToolBar修改返回按钮图标

    使用Toolbar时,有时因为不同的手机设备,不能使用系统默认的主题样式或者图标,必须指定特定的资源,防止APP在不同设备上的效果不一样! 我在使用Toolbar时,把这个布局作为一个公共的了,所以修改起来比较容易,下面是该Toolbar的布局文件:

  • 2018-12-09 22:49:12

    Android 修改Toolbar自带的图标颜色

    toolbar自带的按钮颜色是黑色,现在想修改按钮图标颜色,方法如下: 在布局文件中的Toolbar中增加如下2个 属性

  • 2018-12-09 22:50:46

    Toolbar 标题字体大小及字体颜色

    无师无门遇到点破事也得百度,就单单这破问题 Toolbar 标题字体大小及字体颜色,结果百度一推重复没用的结果,要么一推英文的解释,小学学历的我表示很崩溃!

  • 2018-12-10 00:57:37

    Android沉浸式状态栏(透明状态栏)最佳实现

    在Android4.4之前,我们的应用没法改变手机的状态栏颜色,当我们打开应用时,会出现上图中左侧的画面,在屏幕的顶部有一条黑色的状态栏,和应用的风格非常不协调;为了提供更好的界面交互,google在Android4.4以后提供了设置沉浸式状态栏的方法,对于沉浸式状态栏这个名字存在争议,我们不做讨论,实际的效果其实就是透明的状态栏,然后在状态栏的位置显示我们自定义的颜色,通常为应用的actionbar的颜色,或者是将应用的整体的一张图片也占据到状态栏中,如下图所示: