【Android休眠】之Android休眠机制

R统计师
• 阅读 1244

Android设备停止使用,系统没有什么事情可做,进入休眠状态的功能最终是由内核去实现的;每一类硬件都有自己的驱动,具体的驱动决定怎么进入休眠以及处于何种层次的休眠。比如:对于platform_device,就按照platform_driver定义的规则,在suspend调用的时候,去做上面提到的事情:
struct platform_driver {

int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
void (*shutdown)(struct platform_device *);
int (*suspend)(struct platform_device *, pm_message_t state);
int (*resume)(struct platform_device *);
struct device_driver driver;
const struct platform_device_id *id_table;

};
复制代码
2、Android的特别需求:
比如对于自己的电脑,不用让它休眠好了;但是对于我们形影不离的手机,在休眠的时候还要睁一只眼:来电了要通知你,QQ啊微信啊什么的由信息了也要通知你,所以Android在Linux内核休眠机制之上,提出了“Opportunistic Suspend”。
三、休眠实践
絮絮叨叨这么多,下面让我们切切实实体验下休眠。
1、休眠模式 休眠是分好几种模式的,不同模式实现方式、耗电量不同,以下来自Documentation/power/states.txt:
The kernel supports four power management states generically, though
one is generic and the other three are dependent on platform support
code to implement the low-level details for each state.
This file describes each state, what they are
commonly called, what ACPI state they map to, and what string to write
to /sys/power/state to enter that state

state: Freeze / Low-Power Idle
ACPI state: S0
String: "freeze"

This state is a generic, pure software, light-weight, low-power state.
It allows more energy to be saved relative to idle by freezing user
space and putting all I/O devices into low-power states (possibly
lower-power than available at run time), such that the processors can
spend more time in their idle states.
This state can be used for platforms without Standby/Suspend-to-RAM
support, or it can be used in addition to Suspend-to-RAM (memory sleep)
to provide reduced resume latency.

State: Standby / Power-On Suspend
ACPI State: S1
String: "standby"

This state offers minimal, though real, power savings, while providing
a very low-latency transition back to a working system. No operating
state is lost (the CPU retains power), so the system easily starts up
again where it left off.

We try to put devices in a low-power state equivalent to D1, which
also offers low power savings, but low resume latency. Not all devices
support D1, and those that don't are left on.

State: Suspend-to-RAM
ACPI State: S3
String: "mem"

This state offers significant power savings as everything in the
system is put into a low-power state, except for memory, which is
placed in self-refresh mode to retain its contents.

System and device state is saved and kept in memory. All devices are
suspended and put into D3. In many cases, all peripheral buses lose
power when entering STR, so devices must be able to handle the
transition back to the On state.

For at least ACPI, STR requires some minimal boot-strapping code to
resume the system from STR. This may be true on other platforms.

State: Suspend-to-disk
ACPI State: S4
String: "disk"

This state offers the greatest power savings, and can be used even in
the absence of low-level platform support for power management. This
state operates similarly to Suspend-to-RAM, but includes a final step
of writing memory contents to disk. On resume, this is read and memory
is restored to its pre-suspend state.
复制代码
虽说kernel支持上述四种休眠模式,但具体哪几种可用取决于你的硬件。那么怎么知道自己的Android设备支持的休眠模式呢?
答案:通过/sys/文件系统。查询支持的休眠模式可以cat文件/sys/power/state:
cat /sys/power/state
freeze mem
复制代码
如果我们往/sys/power/state文件echo上面的某一种模式的字符串,系统就会进入相应的休眠模式:
echo "mem" > /sys/power/state
复制代码
如果你搜索过Android休眠相关的内容,在老版本的Android(4.4版本之前)会见有提到PowerManager的setPowerState()方法,该方法即是通过以上方式使系统进入休眠。但自从引入Autosleep后,就不在这么做了,setPowerState()方法也销声匿迹。
2、/sys/power/目录下文件

文件简介:

/sys/power/state:用来控制系统的Power状态。读取该文件可以获取系统支持的休眠模式,写入该文件休眠模式的一种,系统进入到指定的休眠模式。如上所示例。
/sys/power/autosleep:从Android wakelocks补丁集中演化而来,用于取代Android wakelocks中的自动休眠功能。向该文件写入/sys/power/state返回值的某一种,系统会在适当的时候进入指定的休眠的模式;读取该文件返回之前写入的数值。
/sys/power/wake_lock、/sys/power/wake_unlock:即我们常说的休眠锁,如果应用持有休眠锁,系统将无法进入休眠模式。在Android wakelocks时代,写wake_lock获取锁,写wake_unlock释放锁;在AutoSleep时代,具体参见【Android休眠】之AutoSleep
wakeup_count:用于解决“system suspend和system wakeup events之间的同步问题”。
/sys/power/pm_async:状态切换开关,允许/禁止User空间对设备进行异步的suspend和resume操作。
/sys/power/pm_freeze_timeout:系统在执行休眠动作的时候要冻结(freeze)用户控件的进程和内核空间的允许冻结的内核线程,执行这些操作要耗时间吧?该文件指定所需时间的最大值。
https://zhuanlan.zhihu.com/p/...
https://zhuanlan.zhihu.com/p/...
https://zhuanlan.zhihu.com/p/...
https://zhuanlan.zhihu.com/p/...
https://zhuanlan.zhihu.com/p/...
https://zhuanlan.zhihu.com/p/...
https://zhuanlan.zhihu.com/p/...
https://zhuanlan.zhihu.com/p/...
四、其他需要明了的问题
1、Android设备屏幕暗下来的时候,并不是立即就进入了休眠模式;当所有唤醒源都处于de-avtive状态后,系统才会进入休眠。
2、Android设备连着adb线到其他设备的情况下,设备是不会进入休眠模式的。
3、有休眠操作就有唤醒,就需要唤醒源。唤醒源有很多种,在内核注册,比如常用的Power按键。
4、曾经困惑的一个问题:系统怎么知道自己应该进入休眠模式了?它的判断依据是什么?
在wakelock时代,系统休眠过程中去检测休眠锁;如果系统中没有其他部件持有休眠锁,就尝试进入休眠模式,没有异常事件发生的话就进入休眠模式。 Android从4.4开始使用autosleep机制,只要不存在任何active的唤醒源(wakeup_source)了,就进入休眠模式。

点赞
收藏
评论区
推荐文章
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
简
4年前
源码解读Linux等待队列
从源码角度来解读Linux等待队列机制,了解休眠与唤醒的运转原理kernel/include/linux/wait.hkernel/kernel/sched/wait.ckernel/include/linux/sched.hkernel/kernel/sched/core.c一、概述Linux内核的等待队列是非常重要的数据结构,在内核驱动中广为使用,它是
易娃 易娃
4年前
Android开发 - 获取Android设备的唯一标识码(Android 6.0或更高)
在我们的APP开发中,通常需要获取到设备的唯一标识。在Android6.0之前,有很多方法我们可以方便获取到硬件的唯一标识,但是在Android6.0之后,Android系统大幅限制了我们获取设备的硬件信息。Android6.0之前的方法(已过时)1.DEVICE\_ID通getSystem
android保活,有效的代码保活
需要APP暗屏情况下进行后台执行一些任务,但是google现在为了优化手机的体验,以及流畅性,做了很多的限制,电量优化,休眠模式,以及进入深度睡眠状态,进入深入休眠状态系统会根据黑白名单的应用进行管理,杀掉非白名单的后台进程以及网络请求;Android系统的优化是守护后台进程造成了很大困扰,线程之间守护已经是不在可靠,使用wakelock耗电过大也会是系统杀
Stella981 Stella981
3年前
Android起步
AndroidSQLite http://facebook.github.io/stethoAndroid系统架构Android大致可以分为四层架构,五块区域。1\.Linux内核层Android系统是基于Linux2.6内核的,这一层为Android设备的各种硬件提供了底层的驱动,如显示驱动、音频驱动、照相机驱动
Wesley13 Wesley13
3年前
SystemClock.sleep和Thread.sleep源码分析
一、在android中休眠3s钟有2中方法:1、SystemClock.sleep(3000);2、Thread.sleep(3000);二、通过系统源码区别1、SystemClock.sleep(longms)源码:publicstaticvoidsleep(longms){
Wesley13 Wesley13
3年前
Unity横屏
Android下发现Unity里面的Player设置,并不能完全有效,比如打开了自动旋转,启动的时候还是会横屏,修改XML添加以下代码<applicationandroid:icon"@drawable/ic\_launcher"                    android:label"@string/app\_name"
Wesley13 Wesley13
3年前
4412开发板
迅为4412开发板(屏幕翻转)(Android(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwww.eechina.com%2Fkeyword%2FAndroid)4.4设置不锁屏、去除休眠、屏幕休眠等)19.20.1屏幕翻转本节介绍如何把快速设置栏中的“屏幕锁定/自
Wesley13 Wesley13
3年前
1.Linux电源管理
1.休眠方式 在内核中,休眠方式有很多种,可以通过下面命令查看常用的休眠方式有freeze,standby,mem,diskfreeze:冻结I/O设备,将它们置于低功耗状态,使处理器进入空闲状态,唤醒最快,耗电比其它standby,mem,disk方式高standby:除了冻结
Stella981 Stella981
3年前
Android驱动学习
在给Android添加新的驱动后,app要如何使用呢?正常的使用一个设备,需要getService。但是像LED等我们自己添加的硬件驱动,Android源代码根本没有我们自己添加的服务。第一种:我们自己的创建的硬件设备驱动的类是被系统定义为了隐藏类,那么在Android系统中如何使用隐藏类呢?为此我们可以根据android的编译过程可以看到我们添
Wesley13 Wesley13
3年前
JAVA程序设计练习题集答案
一、判断题1.String字符串在创建后可以被修改。(0)2.引用一个类的属性或调用其方法,必须以这个类的对象为前缀。(0final类名)3.当调用一个正在进行线程的stop()方法时,该线程便会进入休眠状态。(0)4.如果一个类声明实现一个接口,但没有实现接口中的所有方法,那么这个类必须是abst