今天轻松一些,整理了一份通过 HiAppEvent 上报的7大类 DFX 事件及其参数手册,帮助大家在日常开发中速查定位问题。或许有人说,现在都AI时代了,要学那么多干嘛?可我想说的是,学习知识永远不会过时,尤其是当下这个时代,踏踏实实的学习知识,可以让你拥有AI时代不可或缺的判断力和洞察力!言归正传,我们进入正题:HiAppEvent 是鸿蒙系统内置的应用事件打点 + 事件订阅能力,属于性能分析套件,系统能力:SystemCapability.HiviewDFX.HiAppEvent,API 9 起正式提供 ArkTS 接口,同时支持 C/C++ NDK 接口,简单的打点举例如下:

import { hiAppEvent } from '@kit.PerformanceAnalysisKit';
// 打点:上报页面加载事件
hiAppEvent.write("page", "page_load", hiAppEvent.EventType.BEHAVIOR, {
  page: "home",
  cost: 120
});
// 订阅:监听崩溃事件
const watcher = {
  onReceive: (info) => {
    console.info("收到事件:", info);
  }
}
hiAppEvent.addWatcher(watcher);

一、7大类DFX事件总览

事件名问题类型通俗解释最低 API
FLUTTER_DART_EXCEPTIONDart 异常Dart 代码有 bugAPI 18
FLUTTER_STABILITY_EVENT稳定性事件引擎检测到不稳定:卡死、GPU 丢失等API 18
FLUTTER_ETS_EXCEPTIONETS 异常ArkTS 插件代码有 bugAPI 18
OTHER_JANK丢帧某一帧画太慢了API 18
OTHER_JANK_STAT丢帧统计一段时间内的丢帧汇总API 18
OTHER_JANK_SCROLL滑动丢帧滑动时某帧超过 50msAPI 18
FrameworkMemAnomaly内存超限Dart 内存超过 1.5GBAPI 26

如果你搜不到某些事件,可能是系统 API 版本太低了

二、FLUTTER_DART_EXCEPTION:Dart 代码异常

触发条件:Dart 代码逻辑抛出的异常

参数类型限制怎么用
frameworkNameString固定 “FLUTTER”,标识用
errorMsgString≤4096 字符确定是什么异常
stackTraceString≤8192 字符定位到代码行
pidInt64关联进程
timeStampInt64发生时刻

errorMsg 的四种高频取值:

errorMsg 示例异常类型怎么修
type ‘Null’ is not a subtype of type ‘String’TypeError加空判断
NoSuchMethodError: … was called on nullNoSuchMethodError用 ?. 安全调用
RangeError: Index value ‘N’ is out of rangeRangeError加边界检查
Bad state: Stream has already been listened toStateError检查 Stream 状态

三、FLUTTER_STABILITY_EVENT:稳定性事件

触发条件:引擎检测到不稳定情况,包括线程卡死、GPU 丢失、引擎创建销毁等。这是一个大类事件,靠 eventName 字段区分子类型:

eventName通俗解释严重度
FLUTTER_THREAD_STUCK某个线程卡死了致命
FLUTTER_GPU_CONTEXT_LOSSGPU 资源被系统回收
FLUTTER_ENGINE_CREATEFlutter 引擎创建了
FLUTTER_ENGINE_DESTROYFlutter 引擎销毁了

四、FLUTTER_ETS_EXCEPTION:ArkTS 插件异常

触发条件:ArkTS 插件代码在处理 MethodChannel 消息时出错。

参数说明怎么用
CONTEXT异常发生在哪个环节确定出错位置,读法见下
ERROR_MSG错误信息确定异常类型
STACK_TRACE堆栈定位到代码行
CONTEXT 值含义排查方向
MethodChannel.onMessage插件接收消息时出错,检查 onMethodCall
MethodChannel.reply处理返回结果时出错,检查 Dart 侧回调
DartMessenger.invokeHandler二进制消息处理出错,检查消息处理器
DartMessenger.handlePlatformMessageResponse消息回复出错,检查回复回调

特点:ETS 异常通常不会导致闪退(被 try-catch 了),但会导致功能用不了。

五、三个 JANK 事件:丢帧

OTHER_JANK,单次丢帧。非滑动场景下某一帧画太慢:

参数怎么判断
missedFrames丢了多少帧,1-3 轻微,>3 严重
startTime / endTime丢帧时间范围,定位发生时刻

OTHER_JANK_STAT,丢帧统计。非滑动场景累计丢了最多 10 帧后批量上报:

参数怎么判断
totalMissedFrames丢帧总量
maxFrameTime最严重一帧画了多久,毫秒
maxMissedFrameRate60/120 正常,低值说明帧率不达标

maxFrameTime 定严重程度:

maxFrameTime严重程度用户感受
<16ms正常无感知
16-50ms轻微偶有顿挫
50-100ms明显可感知卡顿
>100ms严重严重卡顿

OTHER_JANK_SCROLL,滑动丢帧。滑动时某一帧超过 50ms:

参数怎么用
maxFrameTime超过 50ms 用户能感知
totalMissedFrames配合 totalFrames 算丢帧率
totalFrames滑动期间总帧数
recentScrollCount等于 1 说明每次滑动都丢帧
frameId最严重丢帧的帧号,在 Trace 中定位
丢帧率 = totalMissedFrames / totalFrames:
丢帧率严重程度用户感受
<5%正常无感知
5-10%轻微偶有顿挫
10-30%明显明显卡顿
>30%严重严重影响体验

六、FrameworkMemAnomaly:内存超限

触发条件:Dart 内存超过 1.5GB,仅 API 26 及以上上报。description 的格式:

Dart heap memory usage exceeds threshold:total = X MB (old = Y MB, new = Z MB)

三个字段的读法:

字段含义分析方向
total总内存总使用量
oldOld Space,长期对象持续增长等于内存泄漏
newNew Space,临时对象高但 GC 后降,正常

两个注意:低版本只有 HiLog(搜 heap memory);事件触发后停止监控,需要重启引擎恢复。详细排查见 系列内存篇 第 2 节。

七、怎么查看这些事件

方法一,通过 hilog 搜索:

# 搜索所有 HiAppEvent 上报
hdc shell hilog | grep "OH_HiAppEvent_Write"
# 搜索特定事件
hdc shell hilog | grep "FLUTTER_DART_EXCEPTION"
hdc shell hilog | grep "FLUTTER_STABILITY_EVENT"
hdc shell hilog | grep "OTHER_JANK"
hdc shell hilog | grep "FrameworkMemAnomaly"

方法二,查看 faultlog 目录:

# 崩溃日志
hdc shell ls /data/log/faultlog/
hdc file recv /data/log/faultlog/faultlog-xxx ./faultlog.txt
# 卡死日志
hdc file recv /data/log/faultlog/appfreeze-xxx ./appfreeze.txt

上报失败的三种典型报错:

错误日志解决方法
API version too low需 API 18+
reportFrameworkMemAnomaly_ is nullptr需 API 26+
flush isValid_ falseHiAppEvent 没初始化,检查 SO 库加载

八、API 版本要求

功能最低 API低于此版本替代方案
HiAppEvent 事件上报API 18不生成任何事件用 HiLog
HiTrace 扩展接口API 19没有丢帧详情 Trace只有丢帧计数
内存异常上报API 26不上报 FrameworkMemAnomalyHiLog 搜 heap memory

HiLog 日志不受 API 版本限制,始终可用。

九、事件关联速查:看到这个事件,去哪查

看到的事件问题是什么排查步骤
FLUTTER_DART_EXCEPTIONDart 代码异常搜 Unhandled exception 看堆栈
FLUTTER_ETS_EXCEPTIONETS 插件异常按 CONTEXT 确定位置
FLUTTER_THREAD_STUCK (UI)UI 线程卡死看卡死前 5-10 秒日志
FLUTTER_GPU_CONTEXT_LOSSGPU 丢失搜 GpuReclaim 看流程
OTHER_JANK丢帧抓 HiTrace 分析帧耗时
OTHER_JANK_SCROLL滑动丢帧算丢帧率,抓 Trace
FrameworkMemAnomaly内存超限看 old/new 分布,用 DevTools

以上就是本次要分享的内容了,如果遇到对应类似卡顿,丢帧,负载等特定场景问题,可以到这个系列去回顾下对应知识点,希望能帮到大家~ 同时大家也持续关注,会持续更新:

小伙伴们记得点赞+关注

关注 CPF-Flutter 社区

“AI再牛,技术不能丢”

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐