线上最伤体验的三类故障是崩溃(Crash)、卡死(Freeze)和被系统查杀(Killed)。传统处理链路通常是用户报障、研发翻日志、复现、修复,周期以“天”计,而且后台被 LowMemoryKill、主线程超时等隐性故障往往没人知道。HarmonyOS 7 的思路分两层:底层由框架在进程退出前后自动打点,做系统级结构化故障信号采集,开发者无需自行埋点即可拿到崩溃栈、卡死原因和查杀理由;上层用 AI 对结构化信号做聚类与归因,生成修复建议,并与 appRecovery 自恢复联动。下面按“智能发现、精准定位、高效修复”三段拆解落地方法。
系统级故障信号底座主要由 Performance Analysis Kit / AbilityKit 提供三种能力:一是通过 errorManager 注册 ErrorObserver,捕获未处理异常 onUnhandledException;二是通过 appRecovery 在故障发生后自动保存状态并重启应用,恢复到故障前界面;三是通过 faultLogger 或启动时的 LastExitReason 查询上一次故障信息。与此同时,HiAppEvent 会在进程退出前后自动记录 APP_CRASH、APP_FREEZE、APP_KILLED 等结构化事件,是“智能发现”的数据源。没有结构化信号,AI 就无从诊断,因此采集底座是后续归因和修复的前提。
智能发现的第一步,是让应用在故障发生时自动拿到结构化信号,而不是依赖用户手动反馈。可以用 hiAppEvent.addWatcher 订阅系统故障事件:- import { hiAppEvent, hilog } from '@kit.PerformanceAnalysisKit';
- // 订阅崩溃 / 卡死 / 应用终止事件,实现“智能发现”
- hiAppEvent.addWatcher({
- name: 'faultWatcher',
- appEventFilters: [
- {
- domain: hiAppEvent.domain.OS,
- names: [
- hiAppEvent.event.APP_CRASH,
- hiAppEvent.event.APP_FREEZE,
- hiAppEvent.event.APP_KILLED
- ]
- }
- ],
- onReceive: (domain: string, appEventGroups: Array<hiAppEvent.AppEventGroup>): void => {
- for (const group of appEventGroups) {
- for (const info of group.appEventInfos) {
- // 结构化字段直接喂给 AI 做聚类归因
- hilog.error(0x0000, 'fault', `event=${info.name}`);
- hilog.error(0x0000, 'fault', `reason=${info.params['reason']}`);
- hilog.error(0x0000, 'fault', `foreground=${info.params['foreground']}`);
- // external_log 是故障日志在沙箱中的完整路径,可上传做深度分析
- hilog.error(0x0000, 'fault', `external_log=${info.params['external_log']}`);
- }
- }
- }
- });
复制代码 这里要重点关注 APP_KILLED 的 reason 字段,它覆盖了真实线上常见杀手:整机低内存 LowMemoryKill、RSS 超阈值 RssThresholdKiller、主线程卡死超时 ThreadBlock6S、输入响应超时 AppInputBlock、生命周期超时 LifecycleTimeout、温度超限 HighTemperature 等。订阅后,过去“只有用户知道卡死、研发一无所知”的盲区就被填平。
发现之后是精准定位,AI 的诊断价值主要来自对结构化字段的聚类与关联。第一,按 reason 聚类,把 APP_KILLED 的原因聚合后,可以快速判断是“内存压力主导”还是“主线程超时主导”。原文给出的真实案例中,RssThresholdKiller 与 LowMemoryKill 合计占 75%,直接指向内存治理。第二,关联同生命周期故障,用 app_running_unique_id 把一次运行里的 APP_KILLED 与对应 APP_CRASH 日志关联,定位崩溃发生前的最后一次后台状态。第三,过滤正常退出,reason = UserRequest(上滑清理)属于正常行为,聚类时按 foreground 过滤,只关注“前台闪退”等影响体验的异常。对于 APP_CRASH,exception 字段里的 name(异常类型)、frame(崩溃栈)、thread(线程)已经结构化呈现“哪行代码、哪个线程、什么异常”,AI 拿到后可直接给出疑似根因与修复方向,无需人工从海量日志里捞栈。errorManager 还可以作为实时定位入口:- // errorManager 捕获未处理异常,作为“精准定位”的实时入口
- import { errorManager } from '@kit.AbilityKit';
- import { hilog } from '@kit.PerformanceAnalysisKit';
- const faultObserver: errorManager.ErrorObserver = {
- onUnhandledException(errMsg: string): void {
- // errMsg 已包含异常类型与栈摘要,可直接归档 / 上报诊断
- hilog.error(0x0000, 'fault', `未捕获异常: ${errMsg}`);
- }
- };
- // 在 Ability 初始化时注册
- errorManager.on('error', faultObserver);
复制代码
定位之后是高效修复。HarmonyOS 提供两套恢复机制,让故障对用户尽量无感。推荐方式是 appRecovery 主动自恢复:在 AbilityStage.onCreate 中使能,故障时自动保存状态并重启。- import { AbilityStage, appRecovery } from '@kit.AbilityKit';
- import { hilog } from '@kit.PerformanceAnalysisKit';
- export default class MyAbilityStage extends AbilityStage {
- onCreate(): void {
- appRecovery.enableAppRecovery(
- appRecovery.RestartFlag.ALWAYS_RESTART,
- appRecovery.SaveOccasionFlag.SAVE_WHEN_ERROR | appRecovery.SaveOccasionFlag.SAVE_WHEN_BACKGROUND,
- appRecovery.SaveModeFlag.SAVE_WITH_FILE
- );
- }
- }
复制代码 并在 module.json5 中标记可恢复:- {
- "abilities": [
- { "name": "EntryAbility", "recoverable": true }
- ]
- }
复制代码 在 UIAbility 里保存关键状态,原文说明状态大小不超过 200KB、保留 7 天,下次启动可自动恢复页面栈与数据:- import { appRecovery, errorManager, UIAbility } from '@kit.AbilityKit';
- import { window } from '@kit.ArkUI';
- import { hilog } from '@kit.PerformanceAnalysisKit';
- let registerId = -1;
- const callback: errorManager.ErrorObserver = {
- onUnhandledException(errMsg: string): void {
- hilog.error(0x0000, 'fault', `未捕获异常: ${errMsg}`);
- appRecovery.saveAppState(); // 保存现场
- appRecovery.restartApp(); // 自动恢复
- }
- };
- export default class EntryAbility extends UIAbility {
- onWindowStageCreate(windowStage: window.WindowStage): void {
- registerId = errorManager.on('error', callback);
- windowStage.loadContent('pages/index', (err) => { /* ... */ });
- }
- onSaveState(state: object): void {
- // 保存关键业务状态,下次启动恢复
- (state as Record<string, Object>)['lastPage'] = 'pages/Detail';
- }
- }
复制代码 另一套是 FaultLogExtensionAbility(API 21+ 延迟上报):当应用崩溃后长时间未重启,系统会在约 30 分钟后拉起该 ExtensionAbility 进程,回调订阅的 crash / freeze 事件,保证“应用起不来也能拿到故障日志”。在根因定位后,诊断智能体还可基于故障日志生成修复代码,例如原文提到的 DevEco Code 自动修复 Agent,把修复从人工排障压缩到分钟级。
适配时要留意支持矩阵:JS_CRASH / APP_FREEZE 支持“监听 + 状态保存 + 自动重启 + 日志查询”全链路;CPP_CRASH 不支持监听与自恢复,需要依赖 faultLogger 查询,设计容错时要区别对待。
把三段串起来,落地动作可以分三层:端上使用 hiAppEvent.addWatcher 与 errorManager.on('error') 采集,并用 appRecovery 自恢复保体验;云上将结构化事件(含 external_log 路径)上报到 HarmonyOS 开发者中心崩溃服务,获得无需写代码的可视化数据报告与实时聚类;研发侧由诊断智能体消费聚类结果,自动开 Issue 并附修复建议。这样才从“被动救火”转向“主动治未病”。
一次典型崩溃的端到端链路是:未捕获异常触发 errorManager 观测器入队,HiAppEvent 在退出前拿到崩溃事件与 faultlog 路径,回调末尾同步退出,系统触发 onSaveState 保存状态,下次启动恢复界面并上报故障,云端 AI 聚类归因,研发收到带修复建议的告警。用户可能只感觉到一次无感重启,而研发已经在后台拿到了归因与补丁。 |