鸿蒙应用开发—功耗优化(后台任务篇)

功耗优化在鸿蒙移动应用开发中占据着至关重要的地位,它直接关系到用户体验、设备续航以及应用在后台的运行效率。鸿蒙系统作为华为推出的全场景分布式操作系统,在功耗管理方面提供了丰富的特性和API支持。

在开发过程中,我们发现功耗热点主要集中在以下几方面:

  • 后台任务:不合理的使用后台任务会导致设备无法进入休眠状态
  • 网络请求:频繁的网络活动尤其是移动数据使用会显著增加功耗
  • 定位服务:持续高精度的GPS定位会快速耗尽电池
  • 屏幕与图形:不合理的UI刷新策略和动画效果会增加GPU负担
  • 传感器使用:未及时释放的传感器监听会持续消耗电量

那么针对以上几点,一起来详细探讨下如何进行性能优化叭:

一、后台任务(长时任务和短时任务)

1.短时任务的合理使用

短时任务(Short-time Task)适用于应用退至后台后需要临时完成一些耗时较短的操作,如小文件下载、缓存处理或信息发送等。

以下是一个申请短时任务执行计算的demo

typescript 复制代码
import { backgroundTaskManager } from '@kit.BackgroundTasksKit';
import { hiTraceMeter } from '@kit.PerformanceAnalysisKit';
import { util } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';

const totalTimes: number = 50000000; // 循环次数
const calculateResult: string = 'Total time costed = %s ms.'; // 文本格式

@Entry
@Component
struct Index {
  @State message: string = 'Click button to calculate.';
  private requestId: number = 0;

  // 申请短时任务
  requestSuspendDelay() {
    try {
      let delayInfo = backgroundTaskManager.requestSuspendDelay('compute', () => {
        console.info('Request suspension delay will time out.');
        // 任务即将超时,取消短时任务
        this.cancelSuspendDelay();
      })
      this.requestId = delayInfo.requestId;
    } catch (error) {
      console.error(`requestSuspendDelay failed. code is ${(error as BusinessError).code} message is ${(error as BusinessError).message}`);
    }
  }

  // 取消短时任务
  cancelSuspendDelay() {
    backgroundTaskManager.cancelSuspendDelay(this.requestId);
    console.info('Request suspension delay cancel.');
  }

  // 计算任务
  computeTask(times: number): number {
    let start: number = new Date().getTime();
    let a: number = 1;
    let b: number = 1;
    let c: number = 1;
    for (let i: number = 0; i < times; i++) {
      a = a * Math.random() + b * Math.random() + c * Math.random();
      b = a * Math.random() + b * Math.random() + c * Math.random();
      c = a * Math.random() + b * Math.random() + c * Math.random();
    }
    let end: number = new Date().getTime();
    return end - start;
  }

  // 点击回调
  clickCallback = () => {
    this.requestSuspendDelay();
    hiTraceMeter.startTrace('computeTask', 0); // 开启性能打点
    let timeCost = this.computeTask(totalTimes);
    this.message = util.format(calculateResult, timeCost.toString());
    hiTraceMeter.finishTrace('computeTask', 0); // 结束性能打点
    this.cancelSuspendDelay();
  }

  build() {
    Column() {
      Row(){
        Text(this.message)
      }
      Row() {
        Button('开始计算')
          .onClick(this.clickCallback)
      }
      .width('100%')
      .justifyContent(FlexAlign.Center)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

从性能分析数据来看,短时任务执行阶段应用主线程的平均CPU占用率为12.6%,最高达到40.0%;而任务取消后未被挂起阶段的平均CPU占用率降至2.2%,最高28.6%。这表明短时任务确实会显著增加系统资源消耗,因此总结出以下经验:

  • 最小化任务时长:尽可能缩短短时任务的执行时间,避免长时间占用系统资源
  • 避免并发任务:同时运行多个短时任务会导致CPU负载过高,可能引起前台应用卡顿
  • 及时释放资源:任务完成后应立即取消短时任务申请,减少不必要的能耗
  • 异常处理:添加适当的错误处理逻辑,确保任务异常时也能正确释放资源

2.长时任务的适用场景与优化

长时任务(Long-time Task)适用于需要在后台持续运行用户可感知的功能,如音乐播放、导航、录音等。与短时任务不同,长时任务允许应用在后台长时间运行,但需要声明具体的任务类型,并且系统会进行严格的权限校验。

长时任务使用场景

根据官方文档给出的长时任务使用场景,写了一个音视频播放长时任务的demo:

typescript 复制代码
import { backgroundTaskManager } from '@kit.BackgroundTasksKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { common, wantAgent } from '@kit.AbilityKit';

@Entry
@Component
struct MusicPlayer {
  private longTaskId: number = 0;

  // 申请音视频播放长时任务
  requestContinuousTask() {
    try {
      backgroundTaskManager.startBackgroundRunning(getContext(),
        backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK,{
          // 点击通知后,将要执行的动作列表
          // 添加需要被拉起应用的bundleName和abilityName
          wants: [
            {
              bundleName: (getContext() as common.UIAbilityContext).abilityInfo.bundleName,
              abilityName: "EntryAbility"
            }
          ],
          // 指定点击通知栏消息后的动作是拉起ability
          actionType: wantAgent.OperationType.START_ABILITY,
          // 使用者自定义的一个私有值
          requestCode: 0,
          // 点击通知后,动作执行属性
          actionFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG],
        }).then(() => {
        console.info('Audio playback long-term task requested');
        this.startMusicPlayback();
      }).catch((err: BusinessError) => {
        console.error(`Failed to request audio playback task. Code: ${err.code}, message: ${err.message}`);
      });
    } catch (error) {
      console.error(`Exception when requesting audio playback task. Code: ${(error as BusinessError).code}, message: ${(error as BusinessError).message}`);
    }
  }

  // 取消长时任务
  stopContinuousTask() {
    try {
      backgroundTaskManager.stopBackgroundRunning(getContext()).then(() => {
        console.info('Long-term task stopped');
        this.stopMusicPlayback();
      }).catch((err: BusinessError) => {
        console.error(`取消长时任务失败 Code: ${err.code}, message: ${err.message}`);
      });
    } catch (error) {
      console.error(`取消长时任务出现异常 Code: ${(error as BusinessError).code}, message: ${(error as BusinessError).message}`);
    }
  }

  // 模拟音乐播放开始
  startMusicPlayback() {
    console.info('音乐后台播放');
    // 实际音乐播放逻辑...
  }

  // 模拟音乐播放停止
  stopMusicPlayback() {
    console.info('音乐后台播放停止');
    // 实际音乐停止逻辑...
  }

  build() {
    Column() {
      Button('开始音乐后台播放')
        .onClick(() => this.requestContinuousTask())
      Button('停止音乐后台播放')
        .onClick(() => this.stopContinuousTask())
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

对于长时任务,我总结出以下优化点:

  • 按需申请:仅在确实需要时才申请长时任务,任务完成后立即释放
  • 类型匹配:准确声明任务类型,避免滥用通用类型
  • 资源释放:任务停止时释放所有相关资源,包括媒体播放器、定位服务等
  • 适配系统限制:不同任务类型可能有特殊要求,如音视频播放必须使用媒体会话服务
  • 用户感知:对于录音等涉及隐私的任务,必须提供明确的用户提示和授权机制

针对后台任务优化还有其他各个方面,如线程池与任务调度、延迟任务等,欢迎各位小伙伴一起讨论

相关推荐
万少8 小时前
云测试提前定位和解决问题 萤火故事屋 上架流程
前端·harmonyos·客户端
htt232111 小时前
用uniapp开发鸿蒙应用(暂停更新-根据项目更新,现在项目未开始)
华为·uni-app·harmonyos
Geekwaner14 小时前
仓颉与ArkTS
harmonyos
SuperHeroWu71 天前
【HarmonyOS】元服务入门详解 (一)
华为·harmonyos·鸿蒙·元服务·卡片·免安装
Georgewu1 天前
【HarmonyOS】ArkUI-X 跨平台框架入门详解(一)
harmonyos
SuperHeroWu71 天前
【HarmonyOS】元服务概念详解
华为·harmonyos·鸿蒙·概念·元服务·详解
Georgewu1 天前
【HarmonyOS】ArkUI-X一套代码跑多端的跨平台方案概念详解
harmonyos
zhanshuo2 天前
HarmonyOS NEXT 智能场景识别实战:让设备主动思考的关键技术揭秘
harmonyos
zhanshuo2 天前
HarmonyOS分布式能力全解析:手机一放下,音箱自动响起!
harmonyos
zhanshuo2 天前
基于HarmonyOS的智能灯光控制系统设计:从定时触发到动作联动全流程实战
harmonyos