写点什么

ErrorManager 助力高效应对 AppFreeze 问题

  • 2026-09-20
    北京
  • 本文字数:2481 字

    阅读完需:约 8 分钟

AI摘要

HarmonyOS 的 ErrorManager 提供 AppFreeze 主动感知与现场信息采集能力,支持开发者精准定位主线程阻塞问题。文章详解其接入方式与典型根因(如主线程耗时、锁竞争、FFRT超时、libuv 阻塞)。

ErrorManager 可捕获 6 秒级主线程无响应事件并提取上下文日志;

AppFreeze 根因集中于主线程阻塞、多线程锁竞争、FFRT 任务超时三类;

libuv EventLoop 阻塞是鸿蒙 Native 层特有的冻屏诱因。

适合鸿蒙 Native 开发者、性能优化工程师、崩溃/卡顿问题排查工程师阅读。

本原创文章帖发布在华为开发者联盟社区,欢迎开发者前往访问评论交流,更多与该内容相关讨论,请点击原帖查看:ErrorManager助力高效应对AppFreeze问题:Native崩溃日志的AI辅助定位-华为开发者话题 | 华为开发者联盟

前言

做鸿蒙开发的朋友,大概都收到过这类用户反馈:"点了没反应,但 App 没闪退"。界面像被定格了一样,应用还活着,就是不响应。这种卡住但不崩溃的情况,就是 AppFreeze(应用冻屏)。

传统开发模式下,AppFreeze 问题很难定位——开发者只能靠用户描述加零星日志去"猜",效率很低。HarmonyOS 其实早就考虑到了这个痛点,提供了 ErrorManager 错误管理能力,让应用可以主动感知 AppFreeze 事件并获取现场信息。下面就来看看怎么用。

什么是 AppFreeze

AppFreeze 指的是主线程执行任务时超过 6 秒未响应输入事件或未完成页面刷新,用户感觉界面"卡住"了。和崩溃不同,进程还在,只是主线程被阻塞了。

常见原因就几种:

• 主线程干了耗时操作(同步计算、大量数据序列化等)

   • 多线程锁竞争或死锁

   • FFRT 任务执行超时

   • libuv EventLoop 被阻塞

AppFreeze 发生时系统会生成故障报告,但默认存在本地,开发者没法实时拿到。接下来要介绍的 ErrorManager,就是来解决这个问题的。

ErrorManager 核心能力一览

ErrorManager 在 @kit.AbilityKit 包里,提供的接口与 AppFreeze 相关的主要有这几个:

简单说就是,监听 AppFreeze 和链式处理。

快速接入

第一步:导入模块

import { errorManager } from '@kit.AbilityKit';import { BusinessError } from '@kit.BasicServicesKit';
复制代码

第二步:定义回调

function freezeCallback() {    console.error('FreezeHandler', '检测到应用发生冻屏!');    // Get more diagnostic information here    // Report to your service quality monitoring platform}
复制代码

第三步:注册监听

Button('开启Freeze监听').onClick(() => {    try {        errorManager.on('freeze', freezeCallback);        console.info('Freeze监听已开启');    } catch (paramError) {        let code = (paramError as BusinessError).code;        let message = (paramError as BusinessError).message;        console.error(`注册失败: ${code}, ${message}`);    }});
复制代码

三步完成,应用就具备了 AppFreeze 感知能力。冻屏发生时回调会被触发,里面想做什么都行——存日志、上报监控、尝试恢复都行。

进阶用法:链式处理器

实际业务中可能需要分几步处理:先保存现场,再尝试恢复,最后如果实在不行就退出。setDefaultFreezeObserver 支持链式调用,能实现这种场景。

第一个处理器

let firstHandler: errorManager.FreezeObserver = () => {};const firstFreezeHandler: errorManager.FreezeObserver = () => {    console.info('[FirstHandler] 检测到Freeze,开始保存现场...');    // Save diagnostic information locally    if (firstHandler) {        firstHandler(); // Pass to next handler    }};
复制代码

第二个处理器

let secondHandler: errorManager.FreezeObserver = () => {};const secondFreezeHandler: errorManager.FreezeObserver = () => {    console.info('[SecondHandler] 尝试恢复应用...');    // Attempt recovery operation    if (secondHandler) {        secondHandler();    } else {        console.info('[SecondHandler] 恢复失败,准备退出');    }};
复制代码

注册

function initFreezeHandlers() {    // Later registered handlers are called first    errorManager.setDefaultFreezeObserver(firstFreezeHandler);    errorManager.setDefaultFreezeObserver(secondFreezeHandler);}
复制代码

AppFreeze 发生时,后注册的处理器先执行——先是 secondHandler 尝试恢复,失败了再调用 firstHandler 保存现场。

配合 loopObserver 预防 Freeze

除了等 AppFreeze 发生,还可以主动监控。loopObserver 能在主线程处理事件超过设定阈值时提前通知,在问题恶化前介入。

let loopObserver: errorManager.LoopObserver = {    onLoopTimeOut(timeout: number) {        console.warn(`主线程处理超时: ${timeout}ms`);        // Issue hasn't worsened yet, early intervention is possible    }};// Set threshold to 1000mserrorManager.on('loopObserver', 1000, loopObserver);
复制代码

这个适合做"预防性维护"——主线程开始卡的时候就能发现,不用等到真的 AppFreeze。

最佳实践

1. 尽早注册:在 EntryAbility 的 onCreate 里就注册,避免漏掉早期冻屏事件

2. 回调里同步退出:如果无法恢复,在回调链最后调用 process.processManager.exit(0)退出,别让用户对着黑屏发呆

3. 上报诊断信息:时间、堆栈、环境都上报,形成问题分析的数据基础

4. 阈值合理设置:loopObserver 阈值建议从 1000ms 开始调,太短误报多,太长可能错过最佳干预时机

5. 回调保持轻量:回调里别做复杂 IO 或网络请求,避免连锁反应

常见问题

Q:ErrorManager 和 HiAppEvent 有什么区别?

A:ErrorManager 是同步回调,AppFreeze 发生时会立即通知,适合需要立刻处理的场景;HiAppEvent 更像日志归档,适合离线分析。

Q:AppFreeze 监听会影响性能吗?

A:不会。这是基于系统事件触发的,没有 AppFreeze 发生就不会有任何开销。

Q:能注册多个监听器吗?

A:用 on('freeze')注册的监听器相互独立,都会收到回调;用 setDefaultFreezeObserver 注册的是链式调用,按注册顺序逆序执行。

Q:接口的使用范围和回调的时长?

A:只能在主线程使用,且回调有时间限制,不建议做耗时操作,一般耗时 1s 以内,否则可能会有数据丢失风险。

结语

AppFreeze 是个老问题,但 ErrorManager 给了开发者一件趁手的工具。实时感知、链式处理、提前预警——把这些能力用起来,至少能知道问题出在哪、什么时候发生的。


🔗 官网开发者学堂视频:https://developer.huawei.com/consumer/cn/training/result?type2List=201783644516849879&orderBy=1&courseType=5

🔗 社区 DFX 专题文章: https://developer.huawei.com/consumer/cn/forum/subject/2101218731402391001

【扫码加入 HarmonyOS DFX 技术交流群】