低功耗优化概述
低功耗是指设备在运行各种任务时,通过采用一系列技术和策略来降低设备的能耗,从而延长电池寿命和设备使用时间。因为手机等移动设备具有便携、移动的属性,其续航时间的长短直接影响用户对该品牌手机的体验和满意度。移动设备的续航时间越长,用户就可以更长时间地使用设备,无需频繁充电,在户外或旅行场景下提供便利。一般而言,为了提供更长的续航时间,可以采取了多种技术和方法来降低功耗、优化电池管理,如优化软件算法、优化屏幕亮度和显示等。其中,省电模式和深色模式是手机功耗优化中常用的优化手段:
- 省电模式:一种通过调整设备的设置来降低系统功耗的功能,例如适当降低屏幕亮度和CPU性能。
- 深色模式:深色模式是应用程序的一种背景颜色设置,用于将应用程序显示背景颜色改为深色调,例如黑色或深灰色。
为了有效去测量手机运行时的功耗,DevEco Profiler提供实时监控(Realtime Monitor)能力,可帮助开发者实时监控设备资源(如CPU、内存、FPS、GPU、Energy等)使用情况,其中Energy以3s为周期进行刷新,体现统计周期内总功耗以及各耗能部件(包括CPU、Display、GPU、Location、Other)的功耗占用情况。综合考虑业界共识指标和实际用户使用体验,实验将主要对比屏幕显示耗电量、CPU耗电量、GPU耗电量以及最终总耗电量,关键指标如下所示:
- 显示耗电量:显示耗电量是手机耗电的主要来源之一,它通常占总能耗的很大比例,影响显示耗电量的关键因素包括屏幕亮度、显示内容、刷新率等。
- CPU耗电量:高性能的任务通常需要更多的CPU计算能力,导致较高的CPU耗电量,影响CPU耗电量的关键因素包括CPU的工作频率、功耗管理策略以及对任务的调度和分配等。
- GPU耗电量:类似于CPU,高性能的图形任务会导致较高的GPU耗电量,影响GPU耗电量的关键因素包括GPU的工作频率、工作负载、绘制内容、分辨率、绘制帧率等。
- 最终总耗电量:最终总耗电量是指设备在特定使用场景下的总能耗,包括屏幕显示、CPU计算和GPU图形处理等。它反映了设备在某种使用情境下的总体能耗水平。
本文将以 “HMOS世界”APP 为例,通过设置省电模式和深色模式来验证不同场景下对手机功耗的影响,观察手机的电量消耗变化情况。同时本文还探讨了主动降低应用亮度、停止冗余动画两项降低功耗的措施,测试不同条件下的电量消耗情况。实验结果表明:
- 主动省电模式:设置省电模式后,系统会自动调节屏幕亮度、调整灭屏时间等配置项,使得耗电量在显示模块降低明显,总耗电量随之降低约12%。
- 主动深色模式:通过主动切换深色模式,OLED屏幕可以使用更少的像素点和背光,实现更低的亮度和对比度。相对于正常模式,总耗电量降低约24.5%。
- 主动调节屏幕亮度:应用主动发起屏幕亮度调节时,可以通过主动降低应用的亮度来减少显示屏的功耗,延长设备的续航时间。相对于正常模式,总耗电量降幅约为36.9%。
- 停止冗余动画:冗余的动画绘制指的是在屏幕上绘制不必要或重复的动画效果,通过停止冗余动画可以减少GPU的工作量,从而降低GPU的功耗。相对于正常模式,总耗电量降幅约为40.2%。
通过设置省电模式、深色模式、调节屏幕亮度调节、停止冗余动画,最终测量的总耗电量对比如下图所示:
图1 总耗电量对比
功耗测量工具
DevEco Profiler
DevEco Profiler应用调优工具(以下简称为Profiler)内置集成在DevEco Studio内,提供场景化的调优体验,不仅方便开发者及时了解应用或服务的CPU、内存、图形等资源的使用情况,还提供了高效的问题定位能力,帮助开发者快速定位到问题所在代码。使用Profiler测试应用程序功耗的方法如下所示:
- 打开Profiler:在DevEco Studio内可以通过以下三种方式打开Profiler
- 在DevEco Studio顶部菜单栏中选择“View -> Tool Windows -> Profiler”。
- 在DevEco Studio底部工具栏中单击“Profiler”。
- 按“Double Shift”或者“Ctrl+Shift+A”打开搜索功能,搜索“Profiler”。
- 连接设备:将设备通过USB连接到计算机上。
- 选择应用程序:在Profiler中,选择要测试的应用程序并开启Realtime Monitor。
- 进行应用程序操作:在设备上进行应用程序操作,如浏览网页、播放视频等。
- 查看结果:右侧区域展示时间窗内Energy资源的实时使用情况,将鼠标悬浮于统计图中任意位置,打开时间标线,左右移动鼠标并结合时间轴可查看不同时间点上的实时信息。
Profiler耗电量示意图如下所示,详细信息及使用可参考实时监控
图2 ProfilerEnergy模块示意图
说明
- 上图区域展示时间窗内CPU、Memory、FPS、GPU、Energy资源的实时使用情况,将鼠标悬浮于统计图中任意位置,打开时间标线,左右移动鼠标并结合时间轴可查看不同时间点上的实时信息。
- Energy以3s为周期进行刷新,体现统计周期内总功耗以及各耗能部件(包括CPU、Display、GPU、Location、Other)的功耗占用情况。
程控电源
程控电源是一种可以进行电压、电流、功率、电阻等参数控制的电源设备,它可以根据用户设定的参数来输出相应的电压和电流,从而满足不同的测试需求。程控电源可以通过编程控制来模拟不同的负载条件,从而测试应用程序在不同负载下的功耗表现。通过这种方式,开发人员可以更好地了解应用程序的能耗特性,从而针对性地进行优化。
使用程控电源测试应用程序功耗的方法如下所示:
- 连接设备:首先需要将程控电源连接到待测设备的电源输入端,并确保连接正确。
- 设置测试条件:在程控电源上设置测试条件,包括电压、电流、功率等参数。
- 进行应用程序操作:在设备上运行待测应用程序,并进行应用程序操作,如浏览网页、播放视频等。
- 收集数据:在测试过程中,程控电源会实时记录设备的功耗数据,包括电压、电流、功率等信息。
省电模式
原理介绍
HarmonyOS默认提供了电源模式的特性,主要分为以下三类:
- 正常模式:默认的电源模式,无特殊需求的情况下,此模式下的系统亮度、灭屏时间,进入睡眠时间等均适合大部分用户的需要。
- 性能模式:强调性能表现的电源模式,如增加系统亮度、关闭灭屏时间、防止进入睡眠等。
- 省电模式:强调省电表现的电源模式,如降低系统亮度、缩短灭屏时间等。
切换了电源模式后,随之更改的配置项有:
- 灭屏时间:可设置时长或关闭灭屏功能。主要涉及模块为显示。
- 自动调节亮度:可以设置开启或关闭自动调节亮度功能。主要涉及模块为传感器和显示。
- 自动调节屏幕旋转:可以设置开启或关闭自动调节屏幕旋转功能。主要涉及模块为传感器和显示。
- 系统亮度:可以设置0~255的取值。主要涉及模块为显示。
- 震动开关:可以设置开启或关闭震动功能,主要涉及模块为马达。
说明
在电源管理方面,HarmonyOS采用了自动切换配置,通过更改不同的配置项来实现不同的电源模式。例如,在正常模式下,系统会自动调节屏幕旋转,以保证用户在横屏和竖屏模式下都能够获得最佳的视觉效果;而在省电模式下,系统会关闭这一功能,以降低屏幕旋转带来的能耗。
场景案例
当设备电量较低时,系统可以切换至省电模式,以减少设备的能耗并延长电池的使用时间。通过与系统省电模式的配合,应用程序可以更加智能地调整自身的功耗策略,以适应设备电量较低的情况,从而延长设备的续航时间,提供更加稳定和持久的使用体验。
一般而言,获取当前设备的电源模式可以通过以下步骤实现:
- 引入系统电源管理模块power,该模块主要提供重启、关机、查询屏幕状态等接口;
- 调用power的getPowerMode方法来获取当前设备的电源模式。
图3 开启省电模式
在省电模式下,获取当前系统的电源模式的代码如下所示:
import { router } from '@kit.ArkUI';
import common from '@ohos.app.ability.common';
import { LearningResource, ActionButtonView, CommonConstants, ArticleCardButtonView } from '@ohos/common';
// 引入power模块
import { power } from '@kit.BasicServicesKit';
@Component
export struct ArticleCardView {
@Prop isLiked: boolean = false;
@Prop isCollected: boolean = false;
@ObjectLink articleItem: LearningResource;
onCollected?: () => void;
onLiked?: () => void;
build() {
Row({ space: CommonConstants.SPACE_16 }) {
Column() {
...
Row() {
ActionButtonView({
imgResource: $r('app.media.ic_eye_open'),
count: this.articleItem.viewsCount,
textWidth: $r('app.float.view_count_icon_width')
})
// 使用getPowerMode获取当前系统的电源模式,并判断当前是否为省电模式
if (power.getPowerMode() == power.DevicePowerMode.MODE_POWER_SAVE) {
ActionButtonView({
imgResource: this.isLiked ? $r('app.media.btn_good_on') : $r('app.media.btn_good_normal'),
count: this.articleItem.likesCount,
textWidth: $r('app.float.like_icon_width')
})
.onClick(() => {
this.onLiked?.();
})
...
} else {
ArticleCardButtonView({
clickAnimationPath: 'common/lottie/liked_lottie.json',
cancelAnimationPath: 'common/lottie/cancel_liked_lottie.json',
isClicked: this.isLiked,
count: this.articleItem.likesCount,
articleId: this.articleItem.id,
textWidth: $r('app.float.like_icon_width'),
type: 'like',
onClicked: this.onLiked,
normalImage: $r('app.media.btn_like_normal'),
onImage: $r('app.media.btn_like_on')
})
...
}
}
.width(CommonConstants.FULL_PERCENT)
.justifyContent(FlexAlign.SpaceBetween)
}
.layoutWeight(1)
.height(CommonConstants.FULL_PERCENT)
.justifyContent(FlexAlign.SpaceAround)
}
}
}
功耗分析
同一界面下滑动列表项,分别对比正常模式和省电模式来测试关闭和开启省电模式情况下的总耗电量和CPU模块、GPU模块、显示模块的耗电量。最终,使用IDE的Profiler工具测量得到的数据如下所示:
图4 使用省电模式前后耗电量对比
从测试数据可以看出:
- CPU和GPU模块的耗电量几乎没有变化。这表明在测试条件下,这两个模块的能耗表现相对稳定,不受省电模式的影响。
- 显示模块耗电量下降明显,降幅达到13.2%。这表明省电模式对于显示模块的能耗有着显著的影响。
- 总耗电量有部分下降,降幅接近12.0%。
这一结果表明省电模式的使用对设备的节能有着显著的效果,通过降低亮度、开启自动调节亮度等方式,省电模式降低了显示模块的能耗,从而达到了降低总体能耗的目的。
深色模式
原理介绍
通过启用深色模式,可以进一步实现能耗的降低。首先,深色模式使用更少的像素点和背光,因此能够减少能量的消耗。其次,深色模式在OLED屏幕上可以关闭像素点,这一特性进一步减少了能耗。在实际开发过程中,应用需要根据当前设备状态来适配深色模式,开发者可以通过设置分层参数数据实现:
- 新建一个资源目录,选择需要根据深浅颜色模式(Color Mode)区分,进行分层数据读取。
- 在color.json文件中,设计对应组件读取的数据。
场景案例
在应用省电模式后,继续在“我的“界面下设计为深色模式可以在显示模块获得更大的收益,一般而言应用深色模式可以通过以下步骤实现:
- 创建深色模式资源文件夹:在项目的resources文件下,创建深色模式的Dark资源文件夹,如下图1所示。
图5 创建深色模式资源文件夹
- 资源文件适配:为深色模式下的界面设计相应的颜色和图标资源文件。
- 在主题中设置深色模式样式:在应用的主题中定义深色模式的样式,包括背景色、文本颜色、图标颜色等。
- 动态切换模式:在应用中实现动态切换深色模式和浅色模式的功能,使用户可以根据自己的喜好随时切换应用的界面模式。
- 测试和优化:在实现深色模式后,需要进行充分的测试,确保在深色模式下界面的显示效果和用户体验都符合预期,对用户进行友好的提示和引导。
图6 深色模式示意图
功耗分析
同一界面下,分别对比测试关闭和开启深色模式情况下的总耗电量和CPU模块、GPU模块、Display模块的耗电量。最终,使用IDE的Profiler工具检测得到的数据如下所示:
图7 使用深色模式前后耗电量对比
根据测试数据分析,我们可以得出以下结论:
- 在CPU和GPU模块方面,耗电量并没有发生显著变化,保持了相对稳定的状态。这表明在当前测试条件下,CPU和GPU的能耗未受到深色模式的影响。
- 显示模块的耗电量大幅下降,降幅达到了28.6%。
- 综合考虑以上数据,总耗电量有小幅度下降,降幅达到了14.2%。
这一结果表明深色模式的使用对设备的整体能耗具有积极的影响,可以有效降低设备的能耗水平。深色模式通过减少需要点亮的像素点数量,从而有效降低了显示模块的功耗。
其他优化措施
优化措施介绍
在省电模式和深色模式下,根据不同的应用场景,通常还有以下常用的优化方式:
- 主动降低应用亮度:可以通过主动降低应用的亮度来减少显示屏的功耗,延长设备的续航时间。
- 主动降低音量大小:降低设备的音量大小可以减少功耗,尤其是在使用耳机或扬声器时。这一优化方式可以在一定程度上减少设备的能耗,延长电池的使用时间。
- 停止一些冗余动效:减少动效的运行可以降低系统功耗的开销,例如过度的页面切换动画、图标动效等。
- 视频场景数据缓存按聚合方式下载:视频的wifi下载建议一次下载大量内容然后空闲一段时间,不建议连续不断的以小流量的速度下载(如每20s下载一次,每次下载3~5s)。
通过采取以上常用的优化方式,可以在省电模式和深色模式下进一步降低设备的能耗,延长电池的使用时间,提升用户体验。同时,结合测试数据的结果,可以更加明确地了解不同优化方式对设备能耗的影响,从而更好地指导实际的优化工作。
场景案例
在设计和开发应用时,需要考虑不同的使用场景需要不同的优化措施来降低功耗。例如,在运行视频应用程序时,可以采用降低亮度、调整刷新率和关闭不必要的背光等措施来降低功耗。而在运行音频应用程序时,则可以采用关闭不必要的传感器、减少CPU负载等措施来降低功耗。结合场景按需选择优化措施是非常重要的,可以帮助设备在不同的使用场景下提供最佳的性能和用户体验,并最大限度地降低功耗。
- 主动降低应用亮度
主动降低应用亮度总共分为以下几步:
- 根据UIAbility的context的配置信息,判断当前是否深色模式;
- 通过WindowStage的getMainWindowSync方法,获取当前主窗口Window对象;
- 使用Window对象的setWindowBrightness方法设置当前应用的屏幕亮度;
在夜间模式下增加主动降低应用亮度,具体代码实现如下:
export default class EntryAbility extends UIAbility {
...
onWindowStageCreate(windowStage: window.WindowStage) {
...
// 判断当前是否为深色模式
if (this.context?.config?.colorMode == ConfigurationConstant.ColorMode.COLOR_MODE_DARK) {
let windowClass = windowStage.getMainWindowSync();
try {
// 设置当前应用窗口亮度
windowClass.setWindowBrightness(0.2, (err) => {
if (err.code) {
console.error('Failed to set the brightness. Cause: ' + JSON.stringify(err));
return;
}
console.info('Succeeded in setting the brightness.');
});
} catch (exception) {
console.error('Failed to set the brightness. Cause: ' + JSON.stringify(exception));
}
}
}
...
}
- 停止一些冗余动效
在HMOS世界App的案例中,点赞、收藏的动画在省电和深色模式下会消耗更多的资源,可以主动关闭这些冗余动效,关闭的过程主要分以下几步:
- 导入系统电源管理power模块;
- 根据power的getPowerMode获取当前设备的电源模式,并判断当前是否为省电模式;
- 根据实际场景,停止或者替换冗余的动效;
图8 省电和深色模式下停止冗余动效
在省电模式下停止点赞、收藏动画,具体代码实现如下:
import { router } from '@kit.ArkUI';
import common from '@ohos.app.ability.common';
import { LearningResource, ActionButtonView, CommonConstants, ArticleCardButtonView } from '@ohos/common';
import { power } from '@kit.BasicServicesKit';
@Component
export struct ArticleCardView {
@Prop isLiked: boolean = false;
@Prop isCollected: boolean = false;
@ObjectLink articleItem: LearningResource;
onCollected?: () => void;
onLiked?: () => void;
build() {
Row({ space: CommonConstants.SPACE_16 }) {
Column() {
...
Row() {
ActionButtonView({
imgResource: $r('app.media.ic_eye_open'),
count: this.articleItem.viewsCount,
textWidth: $r('app.float.view_count_icon_width')
})
// 判断是否为省电模式
if (power.getPowerMode() == power.DevicePowerMode.MODE_EXTREME_POWER_SAVE) {
// 设置点赞和收藏的图片
ActionButtonView({
imgResource: this.isLiked ? $r('app.media.btn_good_on') : $r('app.media.btn_good_normal'),
count: this.articleItem.likesCount,
textWidth: $r('app.float.like_icon_width')
})
.onClick(() => {
this.onLiked?.();
})
ActionButtonView({
imgResource: this.isCollected ? $r('app.media.btn_favorites_on') : $r('app.media.btn_favorites_normal'),
count: this.articleItem.collectionCount,
textWidth: $r('app.float.star_icon_width')
})
.onClick(() => {
this.onCollected?.()
})
} else {
// 设置点赞、收藏的lottie动画
ArticleCardButtonView({
clickAnimationPath: 'common/lottie/liked_lottie.json',
cancelAnimationPath: 'common/lottie/cancel_liked_lottie.json',
isClicked: this.isLiked,
count: this.articleItem.likesCount,
articleId: this.articleItem.id,
textWidth: $r('app.float.like_icon_width'),
type: 'like',
onClicked: this.onLiked,
normalImage: $r('app.media.btn_like_normal'),
onImage: $r('app.media.btn_like_on')
})
ArticleCardButtonView({
clickAnimationPath: 'common/lottie/collected_lottie.json',
cancelAnimationPath: 'common/lottie/cancel_collect_lottie.json',
isClicked: this.isCollected,
count: this.articleItem.collectionCount,
articleId: this.articleItem.id,
textWidth: $r('app.float.star_icon_width'),
type: 'collect',
onClicked: this.onCollected,
normalImage: $r('app.media.btn_collect_normal'),
onImage: $r('app.media.btn_collect_on')
})
}
}
.width(CommonConstants.FULL_PERCENT)
.justifyContent(FlexAlign.SpaceBetween)
}
.layoutWeight(1)
.height(CommonConstants.FULL_PERCENT)
.justifyContent(FlexAlign.SpaceAround)
...
}
...
}
}
功耗分析
同一界面下,在设置了省电模式和深色模式的前提下,测试主动减少应用亮度前后、去掉冗余动画前后的CPU模块、GPU模块、显示模块的耗电量和总耗电量。最终,使用IDE的Profiler工具检测得到的数据如下所示:
图9 主动降低应用亮度前后耗电量对比
图10 去掉冗余动画前后耗电量对比
从测试数据可以看出:
- 主动降低应用亮度的主要效用体现在显示模块,显示模块降幅约为23.7%。
- 停止冗余动画的主要效用体现在GPU模块,GPU模块降幅约为17.7%。
- 主动降低应用亮度后,总耗电量降幅约为16.4%。而停止点赞、收藏动画后,总耗电量降幅约为5.3%。
总结
针对”HMOS世界”的功耗优化这一场景,分别使用省电模式和深色模式对其优化,再增加其他可选的推荐优化项,测试其在对应的GPU模块和显示模块的耗电量。测试表明,相比较正常模式,当开启省电模式和深色模式后,功耗下降明显,而针对应用需求,主动降低应用亮度、去掉冗余动画等方式后,功耗在对应模块持续下降。其各项对比指标数据如下所示:
性能指标 | 开启省电模式 | 开启深色模式 | 主动降低应用亮度 |
---|---|---|---|
显示耗电量下降率 | 13.2% | 21.9% | 15.4% |
总耗电量下降率 | 12.0% | 12.5% | 12.4% |
GPU耗电量下降率 | 总耗电量下降率 | |
---|---|---|
去掉冗余动画 | 17.7% | 3.3% |
通过以上数据,可以清楚地看到采用省电模式和深色模式可以有效地减少设备的能耗。
- 省电模式能够有效延长电池的使用时间,降低设备的发热和功耗,为用户提供更加持久的设备使用体验。
- 相比亮色界面,深色模式在OLED和AMOLED屏幕上能够显著减少功耗,因为这些屏幕类型在显示黑色时能够关闭相应的像素,从而降低能耗。深色模式不仅能够减少屏幕的功耗,还能够在夜间或低光环境下减少眩光,提高用户的视觉舒适度。
- 除了省电模式和深色模式,根据特定场景进行定制的优化措施也可以进一步降低设备的功耗。并且,定制化的优化措施能够更好地满足用户的实际需求,提供更加个性化和高效的节能方案。
在应用开发中,开发者可以采用一些技术手段来降低应用的功耗为用户提供更加节能高效的应用体验,满足用户对于续航能力的需求。
最后
有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?但是又不知道从哪里下手,而且学习时频繁踩坑,最终浪费大量时间。所以本人整理了一些比较合适的鸿蒙(HarmonyOS NEXT)学习路径和一些资料的整理供小伙伴学习
点击领取→纯血鸿蒙Next全套最新学习资料希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取~~
一、鸿蒙(HarmonyOS NEXT)最新学习路线
有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,内容包含:(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)…等技术知识点。
获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料
二、HarmonyOS Next 最新全套视频教程
三、《鸿蒙 (OpenHarmony)开发基础到实战手册》
OpenHarmony北向、南向开发环境搭建
四、大厂面试必问面试题
五、鸿蒙南向开发技术
六、鸿蒙APP开发必备
完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料
总结
总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。