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 ...
随机推荐
- 【BIEE】存储安装信息的目录
在BIEE中存在一个目录,用于存储BIEE的安装信息,这个文件的目录为 ~/Oracle_BI1/install/setupinfo.txt 我的目录为:E:/BIEE/Oracle_BI1/inst ...
- RandomForest&ROC
# -*- coding: utf-8 -*- # __author__ = 'JieYao' from biocluster.agent import Agent from biocluster.t ...
- Nginx-负载均衡实践(一、对PHP-FPM进行分摊)
应用的服务器分为前端和后端 前端服务器: 负责对静态文件(比如JS.CSS.图片)等的响应, 以及把PHP请求分发到后端服务器 后端服务器: 处理前端服务器分发而来的PHP请求 前端服务器: 192. ...
- Linux 目录和文件操作
Linux常用命令--目录和文件操作 [目录]删除.复制.移动 : 1.删除文件夹用:rmdir 文件夹名 但是rmdir不能删除非空的文件夹,那如何删除非空文件夹呢: 2.通常情况下,删除文件用:r ...
- Docker构建nginx的nginx-rtmp-module视频服务器镜像
文章地址:https://www.cnblogs.com/linyilong3/p/5862595.html GitHub nginx-rtmp-module 及配置 Dockerfile构建配置: ...
- Atitit. 。Jna技术与 解决 java.lang.Error: Invalid memory access
Atitit. .Jna技术与 解决 java.lang.Error: Invalid memory access 1. 原因与解决1 2. jNA (这个ms sun 的)1 3. Code1 4. ...
- THINKPHP3.2视频教程
http://edu.51cto.com/lesson/id-24504.html lunix视频教程 http://bbs.lampbrother.net/read-htm-tid-161465.h ...
- 众数问题(山东理工OJ)
题目描写叙述 给定含有n个元素的多重集合S,每一个元素在S中出现的次数称为该元素的重数.多重集S中重数最大的元素称为众数. 比如,S={1,2,2,2,3.5}.多重集S的众数是2,其重数为3. 对于 ...
- CCNA2.0笔记_NAT
NAT:园区网内的PC是私有地址,整个园区网共享一个公有IP,如果园区网内的PC不做NAT,那么在发数据包给外网的时候会出现传输问题 NAT的原理:改变IP包头,使目的地址.源地址或两个地址在包头中被 ...
- struts-config message-resources配置问题总结
问题:我的app无法读取配置好的ApplicationResources.properties中的内容 解答:文件目录为 /webapp /WEB-INF /classes ApplicationRe ...