转载地址:http://blog.csdn.net/wh_19910525/article/details/8287202

Wake Lock是一种锁的机制, 只要有人拿着这个锁,系统就无法进入休眠, 可以被用户态程序和内核获得. 这个锁可以是有超时的 或者 是没有超时的, 超时的锁会在时间过去以后自动解锁如果没有锁了或者超时了, 内核就会启动休眠的那套机制来进入休眠.

PowerManager.WakeLock 有加锁和解锁两种状态,加锁的方式有两种:

第一种是永久的锁住,这样的锁除非显式的放开,否则是不会解锁的,所以这种锁用起来要非常的小心。

第二种锁是超时锁,这种锁会在锁住后一段时间解锁。

在创建了 PowerManager.WakeLock 后,有两种机制,第一种是不计数锁机制,另一种是计数锁机制。可以通过 setReferenceCounted(boolean value) 来指定,一般默认为计数机制。这两种机制的区别在于,前者无论 acquire() 了多少次,只要通过一次 release()即可解锁。而后者正真解锁是在( --count == 0 )的时候,同样当 (count == 0) 的时候才会去申请加锁。所以 PowerManager.WakeLock 的计数机制并不是正真意义上的对每次请求进行申请/释放每一把锁,它只是对同一把锁被申请/释放的次数进行了统计,然后再去操作。

源码 位置:frameworks/base/core/java/android/os/PowerManager.java

++++++++++++++++++++++++

讲述 应用层 申请的锁 怎么传到kernel下面的,来理解  整个wakelock的框架。  比如android跑起来之后 在 /sys/power/wake_lock 下面的PowerManagerService 的生成过程。
     
1).应用程序申请锁
  Android 提供了现成 android.os.PowerManager 类 , 类中  提供newWakeLock(int flags, String tag)方法 来取得应用层的锁, 此函数的定义  frameworks/base/core/java/android/os/PowerManager.java
      应用程序 在申请wake_lock时 都会有调用以下 部分。
       实例:
        PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, “MyTag”);
        wl.acquire();//申请锁,这里会调用PowerManagerService里面acquireWakeLock()

***********************
        wl.release(); //释放锁,显示的释放锁,如果申请的锁不在此释放,系统就不会进入休眠。

======================================
2). frameworks层
/frameworks/base/services/java/com/android/server/PowerManagerService.java这个类是来管理 所有的应用程序 申请的wakelock。比如音视、频播放器、camera等申请的wakelock 都是通过这个类来 管理的。
static final String PARTIAL_NAME ="PowerManagerService"
nativeAcquireWakeLock(PARTIAL_WAKE_LOCK_ID, PARTIAL_NAME);
上面 这个函数调用Power类 里面的 acquireWakeLock(),此时的PARTIAL_NAME作为参数传递到底层去。

public static native void nativeAcquireWakeLock(int lock, String id);
注:在PowerManagerService 类中没有实现nativeAcquireWakeLock,其实现体在 frameworks/base/core/jni/android_os_Power.cpp中,所以nativeAcquireWakeLock()方法时会调用JNI下的实现方法

3).JNI层的实现
     路径:frameworks/base/core/jni/android_os_Power.cpp //
    static void acquireWakeLock(JNIEnv *env, jobject clazz,  jint lock, jstring idObj)
  {
    **************
      const char *id = env->GetStringUTFChars(idObj, NULL);
      acquire_wake_lock(lock, id);
      env->ReleaseStringUTFChars(idObj, id);
  }
     注:在acquireWakeLock()中调用了 路径下hardware/libhardware_legacy/power/power.c下面的acquire_wake_lock(lock, id)

4).与kernel层的交互
在power.c下的acquire_wake_lock(lock, id)函数如下:
int acquire_wake_lock(int lock, const char* id)
{   
**************
     return write(fd, id, strlen(id));
}
注: fd就是文件描述符,在此 表示”/sys/power/wake_lock”  id就是从PowerManagerService类中传下来的参数即:PARTIAL_NAME = "PowerManagerService"  到此 就是通过 文件系统 来与kernel层 交互的地方。

+++++++++++++++++++++++++++++++++++++++++++++++++++++

PowerManager类被应用程序调用,控制电源设备状态切换:

PowerManager类对外有三个接口函数:

1、void goToSleep(long time); //强制设备进入Sleep状态

Note:在应用层调用该函数, 应用需要 在 源码下编译,用系统签名,否则 调用 此函数 出错;

  2、newWakeLock(int flags, String tag);//取得相应层次的锁

flags参数说明:

    PARTIAL_WAKE_LOCK :保持CPU 运转,屏幕和键盘灯是关闭的。

    SCREEN_DIM_WAKE_LOCK :保持CPU 运转,允许保持屏幕显示但有可能是灰的,关闭键盘灯

    SCREEN_BRIGHT_WAKE_LOCK :保持CPU 运转,保持屏幕高亮显示,关闭键盘灯

    FULL_WAKE_LOCK :保持CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度

ACQUIRE_CAUSES_WAKEUP: 一旦有请求锁时,强制打开Screen和keyboard light

ON_AFTER_RELEASE: 在释放锁时reset activity timer

Note:

如果申请了partial wakelock,那么即使按Power键,系统也不会进Sleep,如Music播放时

如果申请了其它的wakelocks,按Power键,系统还是会进Sleep

3、void userActivity(long when, boolean noChangeLights);//User activity事件发生,设备会被切换到Full on的状态,同时Reset Screen off timer.

PowerManager和WakeLock的操作步骤

  1. PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);通过 Context.getSystemService().方法获取PowerManager实例。
  2. 然后通过PowerManager的newWakeLock ((int flags, String  tag)来生成WakeLock实例。int Flags指示要获取哪种WakeLock,不同的Lock对cpu 、屏幕、键盘灯有不同影响。
  3. 获取WakeLock实例后通过acquire()获取相应的锁,然后进行其他操作,最后使用release()释放(释放是必须的)。
 

Note:

1. 在使用以上函数的应用程序中,必须在其Manifest.xml文件中加入下面的权限:

    <uses-permission android:name="android.permission.WAKE_LOCK" />

<uses-permission android:name="android.permission.DEVICE_POWER" />

2. 所有的锁必须成对的使用, 如果申请了而没有及时释放,会造成系统故障。如申请了partial wakelock,而没有及时释放, 那系统就永远进不了Sleep模式.

Android 电源管理 -- wakelock机制的更多相关文章

  1. Android电源管理-休眠简要分析

    一.开篇 1.Linux 描述的电源状态 - On(on)                                                 S0 -  Working - Standb ...

  2. Android电源管理基础知识整理

    前言 待机.睡眠与休眠的区别? Android开发者官网当中提到"idle states",该如何理解,这个状态会对设备及我们的程序造成何种影响? 进入Doze模式中的idle状态 ...

  3. android(五)----使用WakeLock使Android应用程序保持后台唤醒

    在使用一些产品列如微信.QQ之类的,如果有新消息来时,手机屏幕即使在锁屏状态下也会亮起并提示声音,这时用户就知道有新消息来临了. 但是,一般情况下手机锁屏后,Android系统为了省电以及减少CPU消 ...

  4. Android:PowerManager类 电源管理

    PowerManager类用于对设备电源状态进行管理:PowerManager.WakeLock类用于保持设备常亮:Android中通过各种Lock锁对电源进行控制,需要注意的是加锁和解锁必须成对出现 ...

  5. Android权限管理之Permission权限机制及使用

    前言: 最近突然喜欢上一句诗:"宠辱不惊,看庭前花开花落:去留无意,望天空云卷云舒." 哈哈~,这个和今天的主题无关,最近只要不学习总觉得生活中少了点什么,所以想着围绕着最近面试过 ...

  6. android之WakeLock机制浅析

    转自:http://blog.sina.com.cn/s/blog_4ad7c2540101n2k2.html 应用程序耗电的实质,是所启用的硬件在消耗电量.  手机的耗电单元 CPU: 应用处理器( ...

  7. Android内存管理机制之一:low memory killer

    转载自http://www.miui.com/thread-29268-1-1.html 准备写这个专题之前,心里是有点忐忑的.首先Android内存管理机制相当复杂,想要讲清楚比较困难:其次对于绝大 ...

  8. linux驱动程序之电源管理之标准linux休眠与唤醒机制分析(一)

    1. Based on linux2.6.32,  only for mem(SDR) 2. 有兴趣请先参考阅读: 电源管理方案APM和ACPI比较.doc Linux系统的休眠与唤醒简介.doc 3 ...

  9. 【朝花夕拾】Android性能篇之(六)Android进程管理机制

    前言        Android系统与其他操作系统有个很不一样的地方,就是其他操作系统尽可能移除不再活动的进程,从而尽可能保证多的内存空间,而Android系统却是反其道而行之,尽可能保留进程.An ...

随机推荐

  1. java集成jpush实现客户端推送

    代码地址如下:http://www.demodashi.com/demo/13700.html 前言 java 集成jpush 实现客户端推送 一.准备工作 开发环境: jdk1.6 Eclipse ...

  2. 如何使用Xcode进行高保真原型设计?

    转载自:http://www.guimobile.net/xcode-high-fidelity-prototype-design.html Xcode不仅是开发者用来开发iOS Apps的开发工具, ...

  3. 补习知识:Entity Framework Code First属性映射约定

    Entity Framework Code First与数据表之间的映射方式有两种实现:Data Annotation和Fluent API.本文中采用创建Product类为例来说明tity Fram ...

  4. android获取系统应用大小的方法

    <span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-s ...

  5. nginx-1.2.7 + tcp_proxy_module手动编译安装

    Nginx开源软件默认没有提供TCP协议的负载均衡,下面记录一下我的安装过程: 1. 下载nginx最新稳定版的源码.可访问:http://www.nginx.org 或 linux命令下载到本地: ...

  6. unity, editable mesh

    一,需求 从fbx载入的模型是不可以在unity里编辑的. 我有一人特殊的需求就是想在unity里为mesh的各顶点K动画. 于是需要自己实现一个可编辑(其实只是顶点可以拖动)的mesh. 二,思路 ...

  7. Myeclipse10安装git 完美解决-费元星

    1. 拥有自己的github版本库 这年头,不在GitHub上弄几个项目都不好意思跟人家打招呼. 首先,进入GitHub注册账号,话说人家这页面做的那叫一个舒服啊. 然后,登陆并创建自己的版本库(Re ...

  8. hdu 1711 Number Sequence KMP 基础题

    Number Sequence Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  9. Atitit.jquery 版本新特性attilax总结

    Atitit.jquery 版本新特性attilax总结 1. Jq1.4 1 2. 1.5 1 3. 1.6 3 4. Jq1.7 3 ⒉提升了事件委派时的性能有了大幅度的提升,尤其是在ie7下: ...

  10. redis源码学习_整数集合

    redis里面的整数集合保存的都是整数,有int_16.int_32和int_64这3种类型,和C++中的set容器差不多. 同时具备如下特点: 1.set里面的数不重复,均为唯一. 2.set里面的 ...