Android 电源管理 -- wakelock机制
转载地址: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 的计数机制并不是正真意义上的对每次请求进行申请/释放每一把锁,它只是对同一把锁被申请/释放的次数进行了统计,然后再去操作。
++++++++++++++++++++++++
讲述 应用层 申请的锁 怎么传到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的操作步骤
- PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);通过
Context.getSystemService().方法获取PowerManager实例。 - 然后通过PowerManager的newWakeLock ((int flags, String tag)来生成WakeLock实例。int Flags指示要获取哪种WakeLock,不同的Lock对cpu 、屏幕、键盘灯有不同影响。
- 获取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机制的更多相关文章
- Android电源管理-休眠简要分析
一.开篇 1.Linux 描述的电源状态 - On(on) S0 - Working - Standb ...
- Android电源管理基础知识整理
前言 待机.睡眠与休眠的区别? Android开发者官网当中提到"idle states",该如何理解,这个状态会对设备及我们的程序造成何种影响? 进入Doze模式中的idle状态 ...
- android(五)----使用WakeLock使Android应用程序保持后台唤醒
在使用一些产品列如微信.QQ之类的,如果有新消息来时,手机屏幕即使在锁屏状态下也会亮起并提示声音,这时用户就知道有新消息来临了. 但是,一般情况下手机锁屏后,Android系统为了省电以及减少CPU消 ...
- Android:PowerManager类 电源管理
PowerManager类用于对设备电源状态进行管理:PowerManager.WakeLock类用于保持设备常亮:Android中通过各种Lock锁对电源进行控制,需要注意的是加锁和解锁必须成对出现 ...
- Android权限管理之Permission权限机制及使用
前言: 最近突然喜欢上一句诗:"宠辱不惊,看庭前花开花落:去留无意,望天空云卷云舒." 哈哈~,这个和今天的主题无关,最近只要不学习总觉得生活中少了点什么,所以想着围绕着最近面试过 ...
- android之WakeLock机制浅析
转自:http://blog.sina.com.cn/s/blog_4ad7c2540101n2k2.html 应用程序耗电的实质,是所启用的硬件在消耗电量. 手机的耗电单元 CPU: 应用处理器( ...
- Android内存管理机制之一:low memory killer
转载自http://www.miui.com/thread-29268-1-1.html 准备写这个专题之前,心里是有点忐忑的.首先Android内存管理机制相当复杂,想要讲清楚比较困难:其次对于绝大 ...
- linux驱动程序之电源管理之标准linux休眠与唤醒机制分析(一)
1. Based on linux2.6.32, only for mem(SDR) 2. 有兴趣请先参考阅读: 电源管理方案APM和ACPI比较.doc Linux系统的休眠与唤醒简介.doc 3 ...
- 【朝花夕拾】Android性能篇之(六)Android进程管理机制
前言 Android系统与其他操作系统有个很不一样的地方,就是其他操作系统尽可能移除不再活动的进程,从而尽可能保证多的内存空间,而Android系统却是反其道而行之,尽可能保留进程.An ...
随机推荐
- 【VBA编程】04.使用自定义数据类型
使用自定义数据类型存储输入数据,并通过弹出窗口展示 [代码区域] Type lianxiren ' name As String Sex As String End Type Sub aa() Dim ...
- docker 中 安装 openssh-server
1,首先,需要从docker官网获得centos或Ubuntu镜像 2,当本地已有Ubuntu镜像后(大概200M左右大小),使用如下命令 docker run -t -i ubuntu /bin/b ...
- CSS3使用盒模型实现三栏布局
本篇文章由:http://xinpure.com/css3-box-model-to-implement-a-three-column-layout/ 使用 Position 绝对定位也是可以实现三栏 ...
- 【HTML+CSS】(2)CSS Sprite雪碧图
1. 雪碧图的使用场景 (1). 静态图片.不随用户信息的变化而变化 (2). 小图片.图片容量比較小 (3). 载入量比較大 一些大图不建议拼成雪碧图,比如淘宝站点的导航图片都是使用的雪碧图. 2. ...
- 利用dd命令制作u盘iso镜像
现在安装系统都是用u盘安装,那么制作u盘的iso镜像就是必须的了.现在此类工具倒是不少,但是,好用的不多,有的还收费.唉,还是用dd吧,老配方,老味道. 首先:要df -h一下,看看u盘的盘符,类似 ...
- NGUI 取ScrollView中遮罩区域4个点
用panel.localCorners而不是panel.finalClipRegion,Region还要再换算 首先通过ScrollView取panel,然后取Corners,它返回值代表4个点,映射 ...
- [svc]rsyslog及logrotate小结
[root@node1 logrotate.d]# ls dracut haproxy httpd mcelog nginx ppp psacct syslog yum yum install ngi ...
- [git]git动画教程
git学习资料比较好的有廖雪峰的教程 还有2个动画教程: https://www.zhihu.com/question/38008771 git-scm 廖雪峰-Git教程 git-for ...
- PHP中的正则表达式及模式匹配
PHP中的正则表达式及模式匹配 PHP中对于正则处理文本提供了两种方式,一种是PCRE方式(PCRE库是一个实现了与perl 5在语法和语义上略有差异(详见下文)的正则表达式模式匹配功能的函数集. 当 ...
- ACM_数论_阶乘N!的末尾有几个零 和 末尾有多少个 1 nyoj 954
原文地址 首先阶乘的一个常识要知道就是25!的末尾6位全是0: 前言: <编程之美>这本书,爱不释手! 问题描述: 给定一个整数N,那么N的阶乘N!末尾有多少个0呢?例如:N=10,N!= ...