Android电源管理介绍

这篇具有很好参考价值的文章主要介绍了Android电源管理介绍。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、电源管理基础知识

1.1电源管理的几种状态

Android kernel源码中,定义了三种电源状态,在kernel/power/suspend.c中:

Android电源管理介绍

对应的宏定义/include/linux/suspend.h

Android电源管理介绍

1.2 电源管理状态的介绍:

PM_SUSPEND_ON

设备处于正常工作状态

PM_SUSPEND_STANDBY

设备处于省电状态,但还可以接收某些事件

PM_SUSPEND_MEM

设备进入睡眠状态,保存系统运行的上下文至内存后挂起系统,只有特定外部中断才可以唤醒设备

PM_SUSPEND_TO_IDLE

设备进入空闲状态,冻结用户空间并将外围设备调至低耗电模式,强制将 CPU 进入idle

ADB 查看支持的电源模式

cat /sys/power/state

1.3 Idle State

Android的Idle状态分为二类:CPU Idle和Device Idle

CPU Idle

每一个 CPU 核心都会有一个 idle 进程,idle 进程是当系统没有调度 CPU 资源的时候,会进入 idle 进程,而 idle 进程的作用就是不使用 CPU,以此达到省电的目的。

有关CPU idle的内容可以查看公众号之前的文章《Linux Cpuidle介绍》

Device Idle

Device Idle属于android Doze模式中的概念,即指手机屏幕熄屏、不充电、静置不动

在 Doze 模式下,按照google的官方说法,Wakelocks,网络访问,jobshedule,闹钟,GPS/WiFi扫描都会停止。

Android电源管理介绍

系统会定期退出 Doze 一小段时间,让应用程序完成其延迟的活动。在此维护窗口期间,系统运行所有挂起的同步、作业和警报,并允许应用程序访问网络。

Android电源管理介绍

二、Android电源管理框架

Android系统的电源管理框架分成五个部分:应用层,框架层,Native层,HAL层和内核层。电源管理架构图例如下:

Android电源管理介绍

应用接口层: PowerManager.java 负责向应用程序提供一系列接口,例如wakelock的申请与释放,进而让系统休眠或唤醒

框架层: PowerManagerService.java PowerManagerServic是android电源管理的核心服务,向上提供应用程序接口.向下通过hal层和kernel层来控制待机状态和系统硬件设备状态

HAL层: power.c 接收上层参数,通过写节点与kernel层通信

内核层: Kernel/Power 实现系统电源管理框架机制,为设备电源管理提供基础框架

三、WakeLock

Android中wakelock是一种锁的机制,用于阻止系统进入睡眠状态,只要有任意应用持有wakelock,那么系统就无法进入睡眠状态。

newWakeLock(int flags, String tag)

申请wakelock时有一个关键的参数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

上面4种是互斥的,即只能指定其中之一,但可以与下面两种flag不是互斥的:

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

ON_AFTER_RELEASE:在释放锁时reset activity timer

如果系统申请了PARTIAL_WAKE_LOCK,那么即使按power键,系统也不会进sleep,如music播放时.如果申请了其它的wakelocks,按power键,系统还是会进sleep

wakelock有加锁和解锁两种状态:

一种是永久性锁住,这种锁除非后续放开,否则不会解锁;

另一种是超时锁,这种锁会锁定系统一段时间后会自动解锁。

电源锁的两种类型:

(1)WAKE_LOCK_SUSPEND:阻止系统进入睡眠,属于永久性锁,超时锁为WAKE_LOCK_AUTO_EXPIRE

(2)WAKE_LOCK_IDLE:阻止持有该锁的系统进入idle状态

Android中使用两条链表分别保存处于active状态的suspend lock和idle lock和保存处于inactive状态的wakelock。

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

3.1wakelock在framework层

内核启动完成后,电源管理系统会在文件系统中建立两个节点:

/sys/power/wake_lock

/sys/power/wake_unlock

应用程序可以通过/sys/power/wake_lock申请一个WAKE_LOCK_SUSPEND 类型的锁,通过/sys/power/wake_unlock则可以释放一个锁。内核在进入suspend之前如果检测到某个锁没有释放,则会放弃本次的suspend过程,直到这个锁释放为止.Android持有电源锁后可以让持锁的进程持续执行,即使进入了睡眠模式。

如果应用崩掉或退出,系统会自动释放他们获取的所有电源锁;如果是在服务中获取的,当服务崩掉或注销时也会自动释放;

Framework层有关电源锁的内容是通过PowerManagerService类来实现,这个类是用来管理所有应用程序申请的wakelock,比如音视频播放器,camera等申请的wakelock都是通过这个类来管理的。如:

static final String PARTIAL_NAME = "PowerManagerService"

PARTIAL_NAME作为参数传递到底层去。

ADB 调试命令

echo lockname > /sys/power/wake_lock

加锁“lockname”

echo lockname > /sys/power/wake_unlock

解锁“lockname”

四、Earlysuspend和Lateresume

Early Suspend和Late Resume是Android在标准Linux的基础上增加的一项特性。当用户空间申请进入suspend时,会先进入early suspend状态.外设驱动程序可以注册early suspend回调函数,当进入early suspend时,内核会逐一地调用这些回调函数。例如在进入early suspend后,回调函数会通过屏幕驱动把屏幕和背光都关闭, 但此时系统依然在正常运行。进入early suspend状态以后,一旦所有wakelock被释放,系统马上会进入真正的suspend流程.

Android 4.4起,也就是引入ART的版本,摒弃了early suspend机制,改用了fb event通知机制,后续Android版本只有suspend、resume以及runtime suspend、runtime resume。

结语

本文讲述了Android电源管理模块的主要内容,旨在让读者对于Android电源状态及wakelock有一个初步的认识,方便以后深入介绍内核wakelock的实现和Android的待机唤醒流程.

引文:

[1]https://developer.android.google.cn/training/monitoring-device-state/doze-standby?hl=en

[2] 深入理解LINUX内核(第三版)(美)博韦,西斯特 著,陈莉君,冯锐,牛欣源 译

长按关注内核工匠微信

Linux内核黑科技| 技术文章 | 精选教程文章来源地址https://www.toymoban.com/news/detail-405029.html

到了这里,关于Android电源管理介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • PLL基础知识介绍

    锁相环(PLL, Phase-Locked Loop)包括 三个关键器件: 鉴相器(PD, phase detector)、环路滤波器(loop filter)和压控振荡器(voltage-controlled oscillator)。鉴相器把周期性输入信号的相位与压控振荡器信号的相位进行比较;PD的输出信号是这两个输入信号之间的相位误差的度量。之后该误

    2023年04月19日
    浏览(42)
  • UDS基础知识介绍

    本文介绍UDS的基础知识,便于做汽车诊断的同学知道一些基本原理和概念,希望能对你有点帮助 UDS ( Unified Diagnostic Services 统一的诊断服务 )是一种 通用的诊断服务标准 ,用于汽车电子控制单元(ECU)的诊断和调试。UDS是ISO 14229标准定义的一种通信协议,可以在CAN、LIN等多

    2024年02月15日
    浏览(57)
  • Android Framework基础知识

    哈喽大家好,我是Zzz. 给大家分享一篇Framework入门的基础知识文章,内容纯纯原创。 一、Application,Activity和进程的关系?     Application、Activity只是进程虚拟机运行的一个类对象,只是属于系统的一个组件和进程没有直接联系。Android支持为每个组件可以单独进程方式运行。

    2024年03月24日
    浏览(40)
  • SSD的基础知识介绍

    固态硬盘,英文名Solid State Disk或Solid State Drive,是一种以存储器作为永久性存储器的电脑存储设备。虽然SSD已不是使用“碟盘”来记存数据,也没有用于“驱动”的马达,但是人们依照命名习惯,仍然称为固态硬盘或固态驱动器。固态硬盘分易失性与非易失性两种,我们着重

    2024年02月10日
    浏览(48)
  • ECharts基础知识详细介绍

    ECharts 实例 series 与 dataset ECharts 基础配置 用 option 描述图表 坐标系 一个网页中可以创建多个 ECharts 实例。每个 ECharts 实例中可以创建多个图表和坐标系等等(用 option 来描述)。准备一个 DOM 节点(作为 ECharts 的渲染容器),就可以在上面创建一个 ECharts 实例。每个 ECharts 实

    2024年02月03日
    浏览(48)
  • [Android]JNI的基础知识

    目录 1.什么是JNI   2.配置JNI开发环境NDK 3.创建Native C++类型的项目 4. 了解CMakeLists.txt 文件 5.了解native-lib.cpp 文件 6.在 Android 的 MainActivity 中调用 native-lib.cpp 中实现的本地方法 1.什么是JNI         JNI(Java Native Interface)是一种允许Java代码与本地代码(如C或C++)进行交互的技

    2024年02月11日
    浏览(49)
  • 什么是网关?网关基础知识介绍

    网关的英文名称:gateway,又叫做网间连接器、协议转换器。网关是在采用不同体系结构或协议的网络之间进行互通时,用于提供协议转换、路由选择、数据交换等网络兼容功能的设施。 网关在传输层上以实现网络互连,是最复杂的网络互连设备,仅用于两个高层协议不同的

    2024年02月08日
    浏览(47)
  • 网络安全 | 密码基础知识介绍

    安全问题 保密性:对发送的消息进行获取 完整性:对发送的消息进行篡改 身份伪造:对发送的主体身份进行篡改,a发的消息,篡改为b发的 行为抵赖:对发送的消息进行否认,丧失行为的可追溯性 密码技术 保密性 完整性 真实性 不可否认性 密码发展史 密码起源:狼烟、虎

    2024年02月12日
    浏览(59)
  • 《C++基础知识精讲》专栏介绍

            本专栏深入讲解C++方面的基础知识,帮你理解透彻,灵活运用,适合有一定C/C++基础的程序员阅读。         本专栏一共25篇,已完结,内容覆盖宏、结构体、指针、运算符、构造函数、继承与派生、友元、命名空间、异常处理、模板、STL等各个方面的内容。   

    2024年02月01日
    浏览(60)
  • Android ContentProvider基础知识学习笔记

    1、动态申请权限 2、读取手机联系人 3、创建自己的ContentProvider (1) onCreate()。初始化ContentProvider的时候调用。通常会在这里完成对数据库的创建和升级等操作,返回true表示ContentProvider初始化成功,返回false则表示失败。 (2) query()。从ContentProvider中查询数据。uri参数用于确定查

    2024年04月10日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包