总体上来说Android的电源办理仍是比较简单的, 首要便是经过锁和守时器来切换体系的状况,使体系的功耗降至最低,整个体系的电源办理架构图如下: (注该图来自Steve Guo)
接下来咱们从Java运用层面, Android framework层面, Linux内核层面别离进行详细的评论:
运用层的运用:
Android供给了现成android.os.PowerManager类,该类用于操控设备的电源状况的切换.
该类对外有三个接口函数:
void goToSleep(long time); //强制设备进入Sleep状况
Note:
测验在运用层调用该函数,却不能成功,呈现的过错好象是权限不行, 但在Framework下面的Service里调用是能够的.
newWakeLock(int flags, String tag);//获得相应层次的锁
flags参数阐明:
PARTIAL_WAKE_LOCK: Screen off, keyboard light off
SCREEN_DIM_WAKE_LOCK: screen dim, keyboard light off
SCREEN_BRIGHT_WAKE_LOCK: screen bright, keyboard light off
FULL_WAKE_LOCK: screen bright, keyboard bright
ACQUIRE_CAUSES_WAKEUP: 一旦有恳求锁时强制翻开Screen和keyboard light
ON_AFTER_RELEASE: 在开释锁时reset activity timer
Note:
假如恳求了partial wakelock,那么即便按Power键,体系也不会进Sleep,如Music播映时
假如恳求了其它的wakelocks,按Power键,体系仍是会进Sleep
void userActivity(long when, boolean noChangeLights);//User activity事情产生,设备会被切换到Full on的状况,一起Reset Screen off timer.
Sample code:
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock (PowerManager.SCREEN_DIM_WAKE_LOCK, “My Tag”);
wl.acquire();
…….
wl.release();
Note:
1. 在运用以上函数的运用程序中,有必要在其Manifest.xml文件中参加下面的权限:
2. 一切的锁有必要成对的运用,假如恳求了而没有及时开释会形成体系故障.如恳求了partial wakelock,而没有及时开释,那体系就永久进不了Sleep形式.
Android Framework层面:
其首要代码文件如下:
frameworks\base\core\java\android\os\PowerManager.java
frameworks\base\services\java\com\android\server\PowerManagerService.java
frameworks\base\core\java\android\os\Power.java
frameworks\base\core\jni\android_os_power.cpp
hardware\libhardware\power\power.c
其间PowerManagerService.java是中心, Power.java供给底层的函数接口,与JNI层进行交互, JNI层的代码首要在文件android_os_Power.cpp中,与Linux kernel交互是经过Power.c来完成的, Andriod跟Kernel的交互首要是经过sys文件的方法来完成的,详细请参阅Kernel层的介绍.
这一层的功用相对比较复杂,比方体系状况的切换,背光的调理及开关,Wake Lock的恳求和开释等等,但这一层跟硬件渠道无关,并且由Google担任保护,问题相对会少一些,有爱好的朋友能够自己检查相关的代码.
Kernel层:
其首要代码鄙人列方位:
drivers/android/power.c
其对Kernel供给的接口函数有
EXPORT_SYMBOL(android_init_suspend_lock); //初始化Suspend lock,在运用前有必要做初始化
EXPORT_SYMBOL(android_uninit_suspend_lock); //开释suspend lock相关的资源
EXPORT_SYMBOL(android_lock_suspend); //恳求lock,有必要调用相应的unlock来开释它
EXPORT_SYMBOL(android_lock_suspend_auto_expire);//恳求partial wakelock, 守时时刻到后会主动开释
EXPORT_SYMBOL(android_unlock_suspend); //开释lock
EXPORT_SYMBOL(android_power_wakeup); //唤醒体系到on
EXPORT_SYMBOL(android_register_early_suspend); //注册early suspend的驱动
EXPORT_SYMBOL(android_unregister_early_suspend); //撤销现已注册的early suspend的驱动
供给给Android Framework层的proc文件如下:
/sys/android_power/acquire_partial_wake_lock //恳求partial wake lock
/sys/android_power/acquire_full_wake_lock //恳求full wake lock
/sys/android_power/release_wake_lock //开释相应的wake lock
/sys/android_power/request_state //恳求改动体系状况,进standby和回到wakeup两种状况
/sys/android_power/state //指示当时体系的状况
Android的电源办理首要是经过Wake lock来完成的,在最底层首要是经过如下三个行列来完成其办理:
static LIST_HEAD(g_inactive_locks);
static LIST_HEAD(g_active_partial_wake_locks);
static LIST_HEAD(g_active_full_wake_locks);
一切初始化后的lock都会被刺进到g_inactive_locks的行列中,而当时活动的partial wake lock都会被刺进到g_active_partial_wake_locks行列中, 活动的full wake lock被刺进到g_active_full_wake_locks行列中, 一切的partial wake lock 和full wake lock在过期后或unlock后都会被移到inactive的行列,等候下次的调用.
在Kernel层运用wake lock过程如下:
1. 调用函数android_init_suspend_lock初始化一个wake lock
2. 调用相关恳求lock的函数android_lock_suspend 或 android_lock_suspend_auto_expire恳求lock,这儿只能恳求partial wake lock, 假如要恳求Full wake lock,则需求调用函数android_lock_partial_suspend_auto_expire(该函数没有EXPORT出来),这个命名有点古怪,不要跟前面的android_lock_suspend_auto_expire搞混了.